摘要:小程序很多方法都是異步的原因官方說法天生異步剛接觸小程序的時(shí)候,發(fā)現(xiàn)很多微信提供的都是異步的,如路由跳轉(zhuǎn),設(shè)置和讀取緩存,還有獲取節(jié)點(diǎn)信息等微信的,都是異步的,需要傳入回調(diào)函數(shù)才能獲得結(jié)果,在我們正常的前端開發(fā)中,這些都不是異步的,當(dāng)時(shí)很奇
1. 小程序很多方法都是異步的原因(官方說法:天生異步)
剛接觸小程序的時(shí)候,發(fā)現(xiàn)很多微信提供的api都是異步的,如路由跳轉(zhuǎn),設(shè)置和讀取緩存,還有獲取節(jié)點(diǎn)信息等微信的api,都是異步的,需要傳入回調(diào)函數(shù)才能獲得結(jié)果,在我們正常的前端開發(fā)中,這些都不是異步的,當(dāng)時(shí)很奇怪為什么是這樣的,最近看了微信的一個(gè)開發(fā)教程之后,總算是明白了。微信小程序開發(fā)教程
小程序的底層架構(gòu)是雙線程模式,邏輯層和渲染層是分開的兩個(gè)線程,渲染層指的就是渲染wxml和wxss,邏輯層指的是執(zhí)行js文件,兩個(gè)線程分開運(yùn)行,通過微信客戶端進(jìn)行通信,調(diào)用微信的api的時(shí)候其實(shí)就是執(zhí)行js的線程和微信客戶端通信。
下圖是微信官方文檔里渲染頁面的一個(gè)流程圖
注意事項(xiàng):
上述說了,小程序的渲染層和邏輯層是分開的兩個(gè)線程,執(zhí)行js邏輯的只有一個(gè)線程,所以在js里聲明了的函數(shù),只要有調(diào)用,就算頁面卸載了,最終都會(huì)執(zhí)行,所以要注意的是,一些interval,或者一些注冊(cè)的其他函數(shù),如果不想在頁面離開后繼續(xù)執(zhí)行的話,在頁面卸載的時(shí)候要注銷掉。
先補(bǔ)充一個(gè)知識(shí)點(diǎn):在小程序的appjs的onLaunch里,給全局變量wx添加的屬性,是全局有效的,能在其他頁面中調(diào)用,比如:
onLaunch: function () { wx.aaa = "123456"; wx.bbb = function () { console.log("541521") } } onLoad: function () { console.log(wx.aaa); wx.bbb(); }
之前對(duì)發(fā)布和訂閱一直沒什么概念,但是多學(xué)點(diǎn)東西總沒壞處,近期自己花了點(diǎn)時(shí)間專門看了一下,大概明白了一點(diǎn)。
訂閱:訂閱就是在某個(gè)地方注冊(cè)一個(gè)自定義的事件,供其他地方調(diào)用
發(fā)布:觸發(fā)已經(jīng)訂閱的函數(shù)
下面是我寫的一個(gè)方法,可能會(huì)有一些bug,但是目前沒有發(fā)現(xiàn),要是有問題的話歡迎交流一下
const myEvent = (function() { // 聲明方法 var pub, sub, remove; // 訂閱緩存記錄 var subCache = {}; // 發(fā)布緩存記錄 var pubCache = {}; // 參數(shù)緩存 var paramCache = {}; // 訂閱事件 sub = function(key, fn) { if (!subCache[key]) { subCache[key] = []; } // 添加到訂閱緩存中 subCache[key].push(fn); // 如果有發(fā)布記錄,則直接執(zhí)行函數(shù) if (pubCache[key]) { if (paramCache[key]) { fn.apply(null, paramCache[key]); } else { fn.apply(null); } // 如果把參數(shù)和發(fā)布緩存清除的話,就是只允許單次執(zhí)行 // paramCache[key] = []; // pubCache[key] = undefined; } }; pub = function() { var key = Array.prototype.shift.call(arguments); var fns = subCache[key]; var args = Array.prototype.slice.call(arguments, 0); pubCache[key] = true; paramCache[key] = args; if (!fns || fns.length === 0) { return; } // 有訂閱記錄,則直接執(zhí)行 for (let fn of fns) { fn.apply(null, args); } }; remove = function(key, fn) { if (subCache[key]) { if (fn) { for(let i = 0, len = subCache[key].length; i < len; i++) { if (fn == subCache[key][i]) { subCache[key].splice(i, 1); break; } } } else { // 把所有的緩存全部清除 subCache[key] = undefined; pubCache[key] = undefined; paramCache[key] = undefined; } } }; return { pub: pub, sub: sub, remove: remove }; })(); module.exports = myEvent;
使用方法如下:
在appjs里引入MyEvent,并掛載在wx對(duì)象上
App({ onLaunch: function () { const MyEvent = require("myEvent的路徑"); wx.myEvent = MyEvent; } })
在其中頁面頁面1的onShow里訂閱test1事件,發(fā)布test2事件
onLoad: function(){ wx.myEvent.sub("test1", function () { console.log("test1"); }); }, onShow: function () { wx.myEvent.pub("test2", "test2" + new Date().getTime()); }
在頁面2的onLoad事件里,發(fā)布test1事件,訂閱test2事件
onLoad: function(options) { wx.myEvent.pub("test1"); wx.myEvent.sub("test2", function(a){ console.log(a); }); }
一. 在頁面1的時(shí)候,執(zhí)行了訂閱test1事件,發(fā)布了test2事件,但是test1沒有發(fā)布,訂閱的事件不會(huì)執(zhí)行,test2事件沒有訂閱,也不會(huì)執(zhí)行。
二. 從頁面1跳轉(zhuǎn)到頁面2,發(fā)布了test1事件,直接執(zhí)行之前已經(jīng)注冊(cè)好的test1事件,訂閱test2事件,因?yàn)橛衪est2的發(fā)布事件,訂閱之后直接執(zhí)行,結(jié)果是打印一次test1,打印一次test2。
三. 從頁面2返回到頁面1,執(zhí)行onShow事件,再次發(fā)布test2事件,打印一次test2
四. 從頁面1到頁面2,發(fā)布了test1事件,事件test2重復(fù)訂閱了,訂閱了兩次,打印一次test1。
五. 從頁面2返回頁面1,發(fā)布test2,因?yàn)閠est2事件訂閱了兩次,所以打印了兩次test2,所以要注意在不需要的地方把事件注銷。
在頁面2的onUnload事件里把事件test2注銷掉,在從頁面2回到頁面1的時(shí)候,事件test2已經(jīng)注銷了,不會(huì)再執(zhí)行。
onUnload: function() { wx.myEvent.remove("test2"); }
原理和用法說明:
原理:
全局只有一個(gè)wx對(duì)象,將myEvent掛載在wx上,所以全局也只有一個(gè)wx.myEvent對(duì)象,myEvent里用到了閉包,訂閱的函數(shù)和參數(shù)都有保存在內(nèi)存里,所以能實(shí)現(xiàn)訂閱和發(fā)布的功能。
目前事件訂閱是用的數(shù)組存儲(chǔ),可實(shí)現(xiàn)同一個(gè)事件訂閱多次,如果不需要的話可自行修改成只能訂閱一次的方法。
用法:
一般用于跨頁面的操作,比如在某個(gè)頁面訂閱某個(gè)事件,在另一份頁面執(zhí)行了某項(xiàng)操作之后,發(fā)布該事件,會(huì)直接執(zhí)行訂閱的事件,實(shí)現(xiàn)頁面間的一些數(shù)據(jù)傳遞。
還有也可用于異步請(qǐng)求,先訂閱某個(gè)事件,異步請(qǐng)求數(shù)據(jù),請(qǐng)求數(shù)據(jù)回來之后,再發(fā)布。
使用例子
在使用發(fā)布和訂閱的方法之前,比如新增地址,從列表頁面跳轉(zhuǎn)到新增頁面,在新增頁面新增地址成功之后,將新增的地址放到緩存,接著返回列表頁面,使用navigateBack,在列表頁面的onShow里檢測是否有緩存,有緩存,則重新加載地址列表
使用發(fā)布訂閱的方法之后,可以在列表頁面的onLoad里訂閱新增地址的事件,在新增地址頁面,新增之后,發(fā)布一個(gè)新增地址事件,列表頁面監(jiān)聽到有新增地址事件,則新增一個(gè)地址,瞬間感覺高大上了
用別人的源碼可以加快開發(fā)速度,而且可以學(xué)習(xí)別人的源碼
We UI WeUI 是一套同微信原生視覺體驗(yàn)一致的基礎(chǔ)樣式庫,由微信官方設(shè)計(jì)團(tuán)隊(duì)為微信內(nèi)網(wǎng)頁和微信小程序量身設(shè)計(jì),令用戶的使用感知更加統(tǒng)一。這個(gè)是一個(gè)樣式庫,只提供樣式。
vant-weapp 這個(gè)是一個(gè)組件庫,里面封裝了一些常用的組件,是有贊的vant組件庫的小程序版本,個(gè)人感覺用起來還是挺好用的。
待補(bǔ)充......
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/104218.html
摘要:對(duì)微信小程序進(jìn)行全局配置,決定頁面文件的路徑窗口表現(xiàn)設(shè)置網(wǎng)絡(luò)超時(shí)時(shí)間設(shè)置多等。 微信小程序知識(shí)總結(jié)及案例集錦 微信小程序的發(fā)展會(huì)和微信公眾號(hào)一樣,在某個(gè)時(shí)間點(diǎn)爆發(fā) 學(xué)習(xí)路徑 微信小程序最好的教程肯定是官方的文檔啦,點(diǎn)擊這里直達(dá) 微信官方文檔 認(rèn)真跟著文檔看一遍,相信有vue前端經(jīng)驗(yàn)的看下應(yīng)該就能上手了,然后安裝 微信小程序開發(fā)者工具 新建一個(gè)quick start項(xiàng)目,了解代碼結(jié)構(gòu),...
摘要:官方資料微信公眾平臺(tái)注冊(cè)小程序。官網(wǎng)開發(fā)文檔社區(qū)開發(fā)工具部署微信小程序微信小程序本身不需要部署,在微信開發(fā)工具中直接上傳代碼就行。 為什么 學(xué)習(xí) Java 三年,目前已經(jīng)工作了2年,因?yàn)樽詫W(xué),基礎(chǔ)差,所以打算年末總結(jié)一下常見的基礎(chǔ)知識(shí)和面試點(diǎn); 也可以通過獨(dú)立做一個(gè)項(xiàng)目整合自己工作期間學(xué)習(xí)的知識(shí),加深印象。 但是想著回家或是平時(shí)手機(jī)用的多,做一款A(yù)PP和小程序很方便查看。 項(xiàng)目展示 本...
摘要:前言一直混跡社區(qū)突然發(fā)現(xiàn)自己收藏了不少好文但是管理起來有點(diǎn)混亂所以將前端主流技術(shù)做了一個(gè)書簽整理不求最多最全但求最實(shí)用。 前言 一直混跡社區(qū),突然發(fā)現(xiàn)自己收藏了不少好文但是管理起來有點(diǎn)混亂; 所以將前端主流技術(shù)做了一個(gè)書簽整理,不求最多最全,但求最實(shí)用。 書簽源碼 書簽導(dǎo)入瀏覽器效果截圖showImg(https://segmentfault.com/img/bVbg41b?w=107...
摘要:那些瑣碎的知識(shí)點(diǎn)作者記錄的的很奇特很難記的知識(shí)點(diǎn)。易錯(cuò)知識(shí)點(diǎn)整理注意和的區(qū)別中和都是輸出的作用,但是兩者之間還是有細(xì)微的差別。今天手頭不忙,總結(jié)一下,分享過程中掌握的知識(shí)點(diǎn)。 深入理解 PHP 之:Nginx 與 FPM 的工作機(jī)制 這篇文章從 Nginx 與 FPM 的工作機(jī)制出發(fā),探討配置背后的原理,讓我們真正理解 Nginx 與 PHP 是如何協(xié)同工作的。 PHP 那些瑣碎的知識(shí)...
閱讀 3182·2021-11-22 15:25
閱讀 3860·2021-11-17 09:33
閱讀 3375·2021-11-08 13:15
閱讀 3054·2021-09-22 10:56
閱讀 546·2021-08-31 09:45
閱讀 2758·2019-08-30 13:49
閱讀 3085·2019-08-30 12:52
閱讀 1149·2019-08-29 17:05