微信小程序中使用Promise進(jìn)行異步流程處理的實(shí)例詳解
微信小程序中使用Promise進(jìn)行異步流程處理的實(shí)例詳解
我們知道,JavaScript是單進(jìn)程執(zhí)行的,同步操作會對程序的執(zhí)行進(jìn)行阻塞處理。比如在瀏覽器頁面程序中,如果一段同步的代碼需要執(zhí)行很長時間(比如一個很大的循環(huán)操作),則頁面會產(chǎn)生卡死的現(xiàn)象。
所以,在JavaScript中,提供了一些異步特性,為程序提供了性能和體驗(yàn)上的益處,比如可以將代碼放到setTimeout()中執(zhí)行;或者在網(wǎng)頁中,我們使用Ajax的方式向服務(wù)器端做異步數(shù)據(jù)請求。這些異步的代碼不會阻塞當(dāng)前的界面主進(jìn)程,界面還是可以靈活的進(jìn)行操作,等到異步代碼執(zhí)行完成,再做相應(yīng)的處理。
一段典型的異步代碼類似這樣:
function asyncFunc(callback) { setTimeout(function () { //在這里寫你的邏輯代碼 //... //邏輯代碼結(jié)束,執(zhí)行一個回調(diào)函數(shù) callback(); }, 5000); }
或者:
function getAccountInfo(callback, errorCallback) { wx.request({ url: '/accounts/12345', success: function (res) { //... callback(data); }, fail: function (res) { //... errorCallback(data); } }); }
然后我們這樣調(diào)用:
asyncFunc(function () { console.log("asyncFunc() run complete"); }); getAccountInfo(function (data) { console.log("get account info successfully:", data); }, function () { console.error("get account info failed"); });
這是一種使用了回調(diào)函數(shù)來控制代碼執(zhí)行流程的方式。這樣看起來沒問題,也挺容易理解。
但是,如果我們一段代碼中,異步操作太多,又要保證這些異步操作是有順序的執(zhí)行,那我們的代碼就看起來非常糟糕,就像這樣:
asyncFunc1(function(){
//...
asyncFunc2(function(){
//...
asyncFunc3(function(){
//...
asyncFunc4(function(){
//...
asyncFunc5(function(){
//...
});
});
});
});
});
這樣的代碼可讀性和可維護(hù)性可想而知了。還有,回調(diào)函數(shù)真正的問題在于:
它剝奪了我們使用 return 和 throw 這些關(guān)鍵字的能力。
那有什么辦法來改善這個問題呢?答案是肯定的,Promise這種概念的產(chǎn)生,很好地解決了這一切。關(guān)于什么是Promise,一搜一大把介紹,我這里就不復(fù)制粘貼了,我主要是講一下我們怎么用它來解決我們的問題。
我們來看一下,上面的例子如果使用Promise,它會是什么樣子?我們先將這些函數(shù)變成Promise的方式:
function asyncFunc1(){ return new Promise(function (resolve, reject) { //... }) } // asyncFunc2,3,4,5也實(shí)現(xiàn)成跟asyncFunc1一樣的方式...
然后看一下他們是怎么樣被調(diào)用的:
asyncFunc1() .then(asyncFunc2) .then(asyncFunc3) .then(asyncFunc4) .then(asyncFunc5);
這樣,這些異步函數(shù)就會按照順序一個一個依次執(zhí)行了。
ES6中原生支持了Promise,不過在原生不支持Promise的環(huán)境中,我們有很多第三方庫來支持,比如Q.js和Bluebird。它們一般都除了提供標(biāo)準(zhǔn)Promise的API外,還提供了一些標(biāo)準(zhǔn)之外但非常有用的API,使得異步流程的控制更加優(yōu)雅。
從微信小程序的API文檔中我們可以看到,框架提供的JavaScript API中很多函數(shù)其實(shí)都是異步的,如wx.setStorage(), wx.getStorage(), wx.getLocation()等等,它們也是提供的回調(diào)的處理方式,在參數(shù)中傳入success, fail,complete回調(diào)函數(shù),就可以對運(yùn)行成功或失敗進(jìn)行分別處理。
如:
wx.getLocation({ type: 'wgs84', success: function(res) { var latitude = res.latitude var longitude = res.longitude var speed = res.speed var accuracy = res.accuracy }, fail: function() { console.error("get location failed") } })
我們能不能讓微信小程序的異步API支持Promise呢?答案是肯定的,我們當(dāng)然可以一個一個的用Promise去包裝這些API,但是這個還是比較麻煩的。不過,由于小程序的API的參數(shù)格式都比較統(tǒng)一,只接受一個object參數(shù),回調(diào)都是在這個參數(shù)中設(shè)置,所以,這為我們的統(tǒng)一處理提供了便利,我們可以寫一個非侵入性的工具方法,來完成這樣的工作:
假設(shè)我們將這個工具方法寫到一個名為的util.js的文件中:
var Promise = require('../libs/bluebird.min') //我用了bluebird.js function wxPromisify(fn) { return function (obj = {}) { return new Promise((resolve, reject) => { obj.success = function (res) { resolve(res) } obj.fail = function (res) { reject(res) } fn(obj) }) } } module.exports = { wxPromisify: wxPromisify }
之后,我們來看一下如何使用這個方法,將原來回調(diào)方式的API變成Promise的方式:
var util = require('../utils/util') var getLocationPromisified = util.wxPromisify(wx.getLocation) getLocationPromisified({ type: 'wgs84' }).then(function (res) { var latitude = res.latitude var longitude = res.longitude var speed = res.speed var accuracy = res.accuracy }).catch(function () { console.error("get location failed") })
是不是很容易理解?
以上就是關(guān)于使用Promise處理異步流程,如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
- 微信小程序中使用Async-await方法異步請求變?yōu)橥秸埱蠓椒?/a>
- 詳解將微信小程序接口Promise化并使用async函數(shù)
- 微信小程序 緩存(本地緩存、異步緩存、同步緩存)詳解
- 詳解微信小程序 同步異步解決辦法
- 微信小程序異步處理詳解
- 微信小程序 wx.request方法的異步封裝實(shí)例詳解
- 微信小程序onLaunch異步,首頁onLoad先執(zhí)行?
- 微信小程序中使用ECharts 異步加載數(shù)據(jù)的方法
- 微信小程序之支付后調(diào)用SDK的異步通知及驗(yàn)證處理訂單方法
- 微信小程序 es6-promise.js封裝請求與處理異步進(jìn)程
- 微信小程序利用co處理異步流程的方法教程
- 微信小程序中使用 async/await的方法實(shí)例分析
相關(guān)文章
await vs return vs return await關(guān)鍵區(qū)別
這篇文章主要為大家介紹了await vs return vs return await關(guān)鍵區(qū)別解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12微信小程序?qū)崿F(xiàn)多個按鈕toggle功能的實(shí)例
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)多個按鈕toggle功能的實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-06-06微信小程序 定位到當(dāng)前城市實(shí)現(xiàn)實(shí)例代碼
這篇文章主要介紹了微信小程序 定位到當(dāng)前城市實(shí)現(xiàn)實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02可拖動窗口,附帶鼠標(biāo)控制漸變透明,開啟關(guān)閉功能
可拖動窗口,附帶鼠標(biāo)控制漸變透明,開啟關(guān)閉功能...2006-06-06ECMAScript 6對象的擴(kuò)展實(shí)現(xiàn)示例
這篇文章主要為大家介紹了ECMAScript 6對象的擴(kuò)展實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08Promise靜態(tài)四兄弟實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了Promise靜態(tài)四兄弟實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07