最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

微信小程序中使用Promise進行異步流程處理的實例詳解

來源:懂視網(wǎng) 責編:小采 時間:2020-11-27 22:32:23
文檔

微信小程序中使用Promise進行異步流程處理的實例詳解

微信小程序中使用Promise進行異步流程處理的實例詳解:微信小程序中使用Promise進行異步流程處理的實例詳解 我們知道,JavaScript是單進程執(zhí)行的,同步操作會對程序的執(zhí)行進行阻塞處理。比如在瀏覽器頁面程序中,如果一段同步的代碼需要執(zhí)行很長時間(比如一個很大的循環(huán)操作),則頁面會產(chǎn)生卡死的現(xiàn)象。 所以,
推薦度:
導讀微信小程序中使用Promise進行異步流程處理的實例詳解:微信小程序中使用Promise進行異步流程處理的實例詳解 我們知道,JavaScript是單進程執(zhí)行的,同步操作會對程序的執(zhí)行進行阻塞處理。比如在瀏覽器頁面程序中,如果一段同步的代碼需要執(zhí)行很長時間(比如一個很大的循環(huán)操作),則頁面會產(chǎn)生卡死的現(xiàn)象。 所以,

微信小程序中使用Promise進行異步流程處理的實例詳解

我們知道,JavaScript是單進程執(zhí)行的,同步操作會對程序的執(zhí)行進行阻塞處理。比如在瀏覽器頁面程序中,如果一段同步的代碼需要執(zhí)行很長時間(比如一個很大的循環(huán)操作),則頁面會產(chǎn)生卡死的現(xiàn)象。

所以,在JavaScript中,提供了一些異步特性,為程序提供了性能和體驗上的益處,比如可以將代碼放到setTimeout()中執(zhí)行;或者在網(wǎng)頁中,我們使用Ajax的方式向服務器端做異步數(shù)據(jù)請求。這些異步的代碼不會阻塞當前的界面主進程,界面還是可以靈活的進行操作,等到異步代碼執(zhí)行完成,再做相應的處理。

一段典型的異步代碼類似這樣:

function asyncFunc(callback) {
 setTimeout(function () {
 //在這里寫你的邏輯代碼
 //...

 //邏輯代碼結束,執(zhí)行一個回調函數(shù)
 callback();
 }, 5000);
}

或者:

function getAccountInfo(callback, errorCallback) {
 wx.request({
 url: '/accounts/12345',
 success: function (res) {
 //...
 callback(data);
 },
 fail: function (res) {
 //...
 errorCallback(data);
 }
 });
}

然后我們這樣調用:

asyncFunc(function () {
 console.log("asyncFunc() run complete");
});

getAccountInfo(function (data) {
 console.log("get account info successfully:", data);
}, function () {
 console.error("get account info failed");
});

這是一種使用了回調函數(shù)來控制代碼執(zhí)行流程的方式。這樣看起來沒問題,也挺容易理解。

但是,如果我們一段代碼中,異步操作太多,又要保證這些異步操作是有順序的執(zhí)行,那我們的代碼就看起來非常糟糕,就像這樣:

asyncFunc1(function(){
 //...
 asyncFunc2(function(){
 //...
 asyncFunc3(function(){
 //...
 asyncFunc4(function(){
 //...
 asyncFunc5(function(){
 //...
 });
 });
 });
 });
});

這樣的代碼可讀性和可維護性可想而知了。還有,回調函數(shù)真正的問題在于:

它剝奪了我們使用 return 和 throw 這些關鍵字的能力。

那有什么辦法來改善這個問題呢?答案是肯定的,Promise這種概念的產(chǎn)生,很好地解決了這一切。關于什么是Promise,一搜一大把介紹,我這里就不復制粘貼了,我主要是講一下我們怎么用它來解決我們的問題。

我們來看一下,上面的例子如果使用Promise,它會是什么樣子?我們先將這些函數(shù)變成Promise的方式:

function asyncFunc1(){
 return new Promise(function (resolve, reject) {
 //...
 })
}

 
// asyncFunc2,3,4,5也實現(xiàn)成跟asyncFunc1一樣的方式...

然后看一下他們是怎么樣被調用的:

asyncFunc1()
 .then(asyncFunc2)
 .then(asyncFunc3)
 .then(asyncFunc4)
 .then(asyncFunc5);

這樣,這些異步函數(shù)就會按照順序一個一個依次執(zhí)行了。

ES6中原生支持了Promise,不過在原生不支持Promise的環(huán)境中,我們有很多第三方庫來支持,比如Q.js和Bluebird。它們一般都除了提供標準Promise的API外,還提供了一些標準之外但非常有用的API,使得異步流程的控制更加優(yōu)雅。

從微信小程序的API文檔中我們可以看到,框架提供的JavaScript API中很多函數(shù)其實都是異步的,如wx.setStorage(), wx.getStorage(), wx.getLocation()等等,它們也是提供的回調的處理方式,在參數(shù)中傳入success, fail,complete回調函數(shù),就可以對運行成功或失敗進行分別處理。

如:

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呢?答案是肯定的,我們當然可以一個一個的用Promise去包裝這些API,但是這個還是比較麻煩的。不過,由于小程序的API的參數(shù)格式都比較統(tǒng)一,只接受一個object參數(shù),回調都是在這個參數(shù)中設置,所以,這為我們的統(tǒng)一處理提供了便利,我們可以寫一個非侵入性的工具方法,來完成這樣的工作:

假設我們將這個工具方法寫到一個名為的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
}

之后,我們來看一下如何使用這個方法,將原來回調方式的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")
})

是不是很容易理解?

聲明:本網(wǎng)頁內容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

微信小程序中使用Promise進行異步流程處理的實例詳解

微信小程序中使用Promise進行異步流程處理的實例詳解:微信小程序中使用Promise進行異步流程處理的實例詳解 我們知道,JavaScript是單進程執(zhí)行的,同步操作會對程序的執(zhí)行進行阻塞處理。比如在瀏覽器頁面程序中,如果一段同步的代碼需要執(zhí)行很長時間(比如一個很大的循環(huán)操作),則頁面會產(chǎn)生卡死的現(xiàn)象。 所以,
推薦度:
  • 熱門焦點

最新推薦

猜你喜歡

熱門推薦

專題
Top