1. 程式人生 > >微信小程式非同步API為Promise簡化非同步程式設計

微信小程式非同步API為Promise簡化非同步程式設計

把微信小程式非同步API轉化為Promise。用Promise處理非同步操作有多方便,誰用誰知道。
微信官方沒有給出Promise API來處理非同步操作,而官方API非同步的又非常多,這使得多非同步程式設計會層層回撥,程式碼一複雜,回撥起來就想砸電腦。

於是寫了一個通用工具,把微信官方的非同步API轉化為Promise,方便處理(多)非同步操作。
你可以這樣用:
準備轉化後的方法並暴露出

// /utils/wx-promise.js
import toPromise from '/module/to-promise/src/index'
const toPromiseWx = toPromsie(wx)
export const request = toPromiseWx('requset')
export const getLocation = toPromiseWx('getLocation')
export const setStorage = toPromiseWx('setStorage')
//export 其他你專案中可能用到的非同步API

在其他檔案中使用
在App.js中使用:

`//App.js`
`import { request } from` `'./utils/wx-promise.js'`
`App({`
`onLanuch: () => {`
`request({ url:` `'[http://api.yourapi.com](http://api.yourapi.com/)'` `})`
`.then(() => {`
`//成功後處理`
`})`
`.then(() => {`
`//失敗後處理`
`})`//歡迎加入全棧開發交流圈一起學習交流:864305860
`}`
`})`

在其他page中使用:

`// /page/index.js`
`import { request, setStorage } from` `'../utils/wx-promise.js'`
`page({`
`onLoad: () => {`
`request({ url:` `'[http://api.yourapi.com](http://api.yourapi.com/)'` `})`
`.then(() => {`
`//成功後處理`
`})`
`.then(() => {`
`//失敗後處理`
`})`
`},`
`onHide: () => {`
`setStorage({`
`key:` `'yourkey'``,`
`data:` `'yourvalue'`
`})`
`.then(() => {`
`/儲存成功`
`})`
`.then(() => {`
`//儲存失敗`
`})`
`}`//歡迎加入全棧開發交流圈一起學習交流:864305860
`})`

to-promise是一個轉換微信小程式非同步API為Promise的一個工具庫
優點:
避免小程式非同步程式設計多次回撥帶來的過多回調導致邏輯不清晰,篇幅過長等問題。
藉助於Promise非同步程式設計特點,支援鏈式操作,像同步一樣寫非同步。
轉化後得API幾乎和微信官方API一樣。
使用方法:
安裝
使用git安裝到專案根目錄/module,

git clone https://github.com/tornoda/to-promise
或直接下載放入專案目錄下如:/module
在需要用到的地方引入
import toPromise from '/module/to-promise/src/index'
繫結微信全域性物件(wx)到函式,以便可以取到微信得API
const toPromiseWx = toPromise(wx)
開始轉化你需要得非同步API
//apiName為微信非同步方法名,如對wx.request()進行轉化
const request = toPromiseWx('request')
//直接使用request方法

舉例:

import toPromise from '/module/to-promise/src/index'
//轉換wx.getStorage()
const getStorage = toPromsie(wx)('getStorage') 
//使用
getStorage({ key: 'test' })
 .then(//歡迎加入全棧開發交流圈一起學習交流:864305860
  (res) => {
   //res的值與wx.getStorage({ success: (res) => {} })中的res值一樣
   //res = {data: 'keyValue'}
   console.log(res.data)//控制檯列印storage中key對於的value
   return res.data//如果需要繼續鏈式呼叫轉化後的api,需要把值顯示返回
  },
  (err) => {
   //err的值與wx.getStorage({ success: (err) => {} })中的err值一樣
   throw err
  }
 )//歡迎加入全棧開發交流圈一起學習交流:864305860

返回
(function): 引數(string)為小程式非同步方法名。返回一個函式,該函式的引數與返回值如下。
引數:(object) 對應wx小程式非同步方法中的引數(OBJECT)除去success與fail後的物件。例如:
官方APIwx.getLocation(OBJECT)的OBJECT接受如下屬性: type altitude success fail complete,那麼去除(success fail)後為:type altitude complete。
返回: (pending Promsise) 返回一個未知狀態的Promise物件,在該物件上呼叫.then(onFulfilled, onRejected)方法來處理對用成功或失敗的情況。onFulfilled為請求成功後呼叫的回撥函式,引數為返回值,onRejected為請求失敗後的回撥函式,引數為返回的錯誤資訊。
簡單點來說,

const getLocation = toPromiseWx('getLocation')
getLocation({
 type: 'wgs84',
 altitude: true,
 complete: () => { console.log('to-promsise is awesome') }
}).then(
 (res) => {//dosomething if succeed},
 (err) => {//dosomething if failed}
)

與下面官方呼叫等價

wx.getLocation({
 type: 'wgs84',//歡迎加入全棧開發交流圈一起學習交流:864305860
 altitude: true,
 complete: () => { console.log('to-promsise is awesome') },
 success: (res) => {//dosomething if succeed},
 fail: (err) => {//dosomething if failed}
})

應用場景舉例
單次非同步呼叫,參見API最後
多次非同步操作呼叫,且每下一次呼叫都會用到前一次返回的結果。
如:獲得GPS資訊後,根據GPS資訊獲取天氣資訊,取得天氣資訊後立馬存入localStorage。

`import toPromise from` `'/module/to-promise/src/index'`
`const toPromiseWx = toPrmise(wx)`
`//方法轉換`
`const getLocation = toPromiseWx(``'getLocation'``)`
`const request = toPromiseWx(``'request'``)`
`const setStorage = toPromiseWx(``'setStorage'``)`
`//鏈式寫邏輯`
`getLocation()` `//獲取位置資訊`
`.then(`
`(res) => {` `//位置獲取成功後的處理,res為返回資訊`
`//處理res後返回有用的資訊,這裡直接返回res,用於演示`
`return` `Promise.resolve(res)` `//必須`
`},`
`(err) => {` `//位置獲取失敗後的錯誤處理,err為錯誤資訊`
`//錯誤處理`
`return` `Promise.resolve(err)` `//必須`
`}`
`)`
`.then(`
`(res) => {` `//根據位置獲取成功後的資訊,請求天氣資訊`
`return` `request({ url:` `'[http://api.weather.com](http://api.weather.com/)'``}) //返回一個pending 狀態下的Promise`
`}`
`)`//幫助突破技術瓶頸,提升思維能力
`.then(`
`(res) => {` `//天氣獲取成功後存入storage的回撥`
`setStorage({`
`key:` `'test'``,`
`data:` `'res'`
`})`
`},`
`(err) => {`
`//天氣獲取失敗後執行這裡,err為獲取天氣失敗的錯誤資訊`
`}`
`)`

如果使用官方的API寫上述邏輯,程式碼是這樣的:

`wx.getLocation({`
`success: (res) => {`
`//some transformation with res`
`wx.request({`
`url:` `'[http://api.weather.com](http://api.weather.com/)'``,`
`success: (res) => {`
`wx.setStorage({`
`success: () => {`
`//do something`
`},`
`fail: (err) => {`
`//do something if err happend`
`}`
`})`
`},`
`fail: (err) => {`
`//do something if err happend`
`}`//歡迎加入全棧開發交流圈一起學習交流:864305860
`})`//面向1-3年前端人員
`},`//幫助突破技術瓶頸,提升思維能力
`fail: (err) => {`
`//do something if err happend`
`})`
`//層層回撥,麻煩

結語

感謝您的觀看,如有不足之處,歡迎批評指正。

本次給大家推薦一個免費的學習群,裡面概括移動應用網站開發,css,html,webpack,vue node angular以及面試資源等。
對web開發技術感興趣的同學,歡迎加入Q群:864305860,不管你是小白還是大牛我都歡迎,還有大牛整理的一套高效率學習路線和教程與您免費分享,同時每天更新視訊資料。
最後,祝大家早日學有所成,拿到滿意offer,快速升職加薪,走上人生巔峰。