小程序的一些小知识总结
小程序很多方法都是异步的原因刚接触小程序的时候,发现很多微信提供的api都是异步的,如路由跳转,设置和读取缓存,还有获取节点信息等微信的api,都是异步的,需要传入回调函数才能获得结果,在我们正常的前端开发中,这些都不是异步的,当时很奇怪为什么是这样的,最近看了微信的一个开发教程之后,总算是明白了。?微信小程序开发教程 小程序的底层架构是双线程模式,逻辑层和渲染层是分开的两个线程,渲染层指的就是渲染wxml和wxss,逻辑层指的是执行js文件,两个线程分开运行,通过微信客户端进行通信,调用微信的api的时候其实就是执行js的线程和微信客户端通信 下图是微信官方文档里渲染页面的一个流程图 注意事项: 上述说了,小程序的渲染层和逻辑层是分开的两个线程,执行js逻辑的只有一个线程,所以在js里声明了的函数,只要有调用,就算页面卸载了,最终都会执行,所以要注意的是,一些interval,或者一些注册的其他函数,如果不想在页面离开后继续执行的话,在页面卸载的时候要注销掉。 发布和订阅模式先补充一个知识点:在小程序的appjs的onLaunch里,给全局变量wx添加的属性,是全局有效的,能在其他页面中调用,比如: onLaunch: function () {
wx.aaa = '123456';
wx.bbb = function () { console.log('541521') }
}
onLoad: function () {
console.log(wx.aaa);
wx.bbb();
}
之前对发布和订阅一直没什么概念,但是多学点东西总没坏处,近期自己花了点时间专门看了一下,大概明白了一点。 订阅:订阅就是在某个地方注册一个自定义的事件,供其他地方调用 发布:触发已经订阅的函数 下面是我写的一个方法,可能会有一些bug,但是目前没有发现,要是有问题的话欢迎交流一下 var MyEvent = (function () {
// 声明方法
var pub,sub,remove;
// 订阅缓存记录
var subCache = {};
// 发布缓存记录
var pubCache = {};
// 参数缓存
var paramCache = {};
// 订阅事件
sub = function (key,fn) {
if (!subCache[key]) {
subCache[key] = [];
}
// 添加到订阅缓存中
subCache[key].push(fn);
// 如果有发布记录,则直接执行函数
if (pubCache[key]) {
if (paramCache[key]) {
fn.apply(null,paramCache[key]);
} else {
fn.apply(null);
}
pubCache[key] = undefined;
}
};
pub = function () {
var key = Array.prototype.shift.call(arguments);
var fns = subCache[key];
// 没有订阅过,则将参数缓存,待订阅的时候直接执行
if (!fns || fns.length === 0) {
pubCache[key] = true;
paramCache[key] = Array.prototype.slice.call(arguments,0);
return;
}
// 有订阅记录,则直接执行
for (let fn of fns) {
fn.apply(arguments);
}
};
remove = function (key) {
// 把所有的缓存全部清除
subCache[key] = undefined;
pubCache[key] = undefined;
paramCache[key] = undefined;
};
return {
pub: pub,sub: sub,remove: remove
};
})();
module.exports = MyEvent;
使用方法如下: 在appjs里引入MyEvent,并挂载在wx对象上 App({
onLaunch: function () {
const MyEvent = require('myEvent的路径');
wx.myEvent = MyEvent;
}
})
在其中页面页面1的onShow里订阅test1事件,发布test2事件 onLoad: function(){
wx.myEvent.sub('test1',function () {
'test1');
});
},onShow: function () {
wx.myEvent.pub('test2','test2' + new Date().getTime());
}
在页面2的onLoad事件里,发布test1事件,订阅test2事件 );
wx.myEvent.sub(function(a){
console.log(a);
});
}
一. 在页面1的时候,执行了订阅test1事件,发布了test2事件,但是test1没有发布,订阅的事件不会执行,test2事件没有订阅,也不会执行。 二. 从页面1跳转到页面2,发布了test1事件,直接执行之前已经注册好的test1事件,订阅test2事件,因为有test2的发布事件,订阅之后直接执行,结果是打印一次test1,打印一次test2。 三. 从页面2返回到页面1,执行onShow事件,再次发布test2事件,打印一次test2 四. 从页面1到页面2,发布了test1事件,事件test2重复订阅了,订阅了两次,打印一次test1。 五. 从页面2返回页面1,发布test2,因为test2事件订阅了两次,所以打印了两次test2,所以要注意在不需要的地方把事件注销。 在页面2的onUnload事件里把事件test2注销掉,在从页面2回到页面1的时候,事件test2已经注销了,不会再执行。 onUnload: function() {
wx.myEvent.remove('test2');
}
原理和用法说明: 原理: 全局只有一个wx对象,将myEvent挂载在wx上,所以全局也只有一个wx.myEvent对象,myEvent里用到了闭包,订阅的函数和参数都有保存在内存里,所以能实现订阅和发布的功能。 目前事件订阅是用的数组存储,可实现同一个事件订阅多次,如果不需要的话可自行修改成只能订阅一次的方法。 用法: 一般用于跨页面的操作,比如在某个页面订阅某个事件,在另一份页面执行了某项操作之后,发布该事件,会直接执行订阅的事件,实现页面间的一些数据传递。 还有也可用于异步请求,先订阅某个事件,异步请求数据,请求数据回来之后,再发布。 待补充...... (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |