国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

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

2019-11-19 15:45:52
字體:
來源:轉載
供稿:網友

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

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

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

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

function asyncFunc(callback) { setTimeout(function () {  //在這里寫你的邏輯代碼  //...  //邏輯代碼結束,執行一個回調函數  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");});

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

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

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

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

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

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

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

function asyncFunc1(){ return new Promise(function (resolve, reject) {  //... })} // asyncFunc2,3,4,5也實現成跟asyncFunc1一樣的方式...

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

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

這樣,這些異步函數就會按照順序一個一個依次執行了。

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

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

如:

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的參數格式都比較統一,只接受一個object參數,回調都是在這個參數中設置,所以,這為我們的統一處理提供了便利,我們可以寫一個非侵入性的工具方法,來完成這樣的工作:

假設我們將這個工具方法寫到一個名為的util.js的文件中:

var Promise = require('../libs/bluebird.min')  //我用了bluebird.jsfunction 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")})

是不是很容易理解?

 以上就是關于使用Promise處理異步流程,如有疑問請留言或者到本站社區交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 扎囊县| 江孜县| 灵丘县| 莫力| 海晏县| 新龙县| 桐城市| 安康市| 铜陵市| 射洪县| 南郑县| 佛教| 枣强县| 汤原县| 五台县| 察哈| 牡丹江市| 东阿县| 金沙县| 普宁市| 九龙县| 营口市| 怀仁县| 汶川县| 西青区| 泸溪县| 高邑县| 金沙县| 乌鲁木齐县| 阿城市| 重庆市| 法库县| 长岛县| 襄汾县| 突泉县| 土默特右旗| 吉木乃县| 玉溪市| 荣成市| 肥乡县| 大姚县|