1. 程式人生 > >微信小程式相容 async / await 方案

微信小程式相容 async / await 方案

要使用 ES7 的 async / await 的話,只靠微信開發者工具中的 Babel 轉換工具是不夠的,它還需要額外的 Babel 外掛來編譯 async / await 程式碼,這裡我們可以做如下配置。

配置步驟如下:

1. 引入 regenerator 包

在自己的測試專案下 npm install --save-dev regenerator,

然後把 node_modules 下的整個 regenerator-runtime 資料夾拷貝到專案的 packages 目錄(整個目錄可以自己定)下。

2. 引入程式碼

在需要用到 async / await 特性的檔案中,引入 regenerator 庫。

import regeneratorRuntime from '../../packages/regenerator-runtime/runtime-module';

然後可以放心的在程式碼中使用 async / await 進行非同步處理了。

3. 封裝wxRequest,讓微信的wx.request API支援async-await語法

// 專案域名
const host = 'https://shouyin.xxx.com';


const wxRequest = async (url, params = {}) => {
  Object.assign(params, {
    token: wx.getStorageSync('token')
  })
  // 所有的請求,header預設攜帶token
  let header = params.header || {
    'Content-Type': 'application/json',
    'token': params.token || ''
  }
  let data = params.data || {}
  let method = params.method || 'GET'
  // hideLoading可以控制是否顯示載入狀態
  if (!params.hideLoading) {
   wx.showLoading({
     title: '載入中...',
   })
  }
  let res = await new Promise((resolve, reject) => {
    wx.request({
      url: host + url,
      method,
      data,
      header,
      success: (res) => {
        if (res && res.statusCode == 200) {
          resolve(res.data)
        } else {
          reject(res)
        }
      },
      fail: (err) => {
        reject(err)
      },
      complete: (e) => {
        wx.hideLoading()
      }
    })
  })
  return res
}

export {
  wxRequest
}

封裝好後就可以在js檔案中使用了,使用方法如下:

import regeneratorRuntime from '../../packages/regenerator-runtime/runtime-module.js'
import {
  wxRequest
} from '../../utils/util.js'

Page({
  data: {
   list:[],
   count: 0,
   page: 1,
   limit: 10
  },
  onLoad: function() {
    this.getList()
    // 請求已經結束 做其他事
  },
  getList: async function() {
    await wxRequest('/test',{
      hideLoading: true,
      data: {
        limit: this.data.limit,
        page: this.data.page
      }
    }).then((ret) => {
      this.setData({
        list: ret.data.data,
        count: ret.data.num
      })
    })
  }
})

封裝帶來的最大的好處是擴充套件方便,支援了async/await語法後,任何非同步操作API都可以像同步一樣執行,比如說多圖上傳,圖片都上傳成功後後端會返回新的圖片地址,現在可以這麼做:

任務:小程式上傳圖片到伺服器,最多上傳三張,前端可以刪除圖片

使用到的API有兩個:wx.uploadFile  wx.chooseImage

imgList是wx.chooseImage成功後返回的圖片臨時地址

Page({
  data: {
    imgList:[]
  },
  onSub: async function() {
     // 點選提交後,開始上傳圖片
     let imgUrls = []
     for (let index = 0; index < this.data.imgList.length; index++) {
       await this.uploadFile(this.data.imgList[index]).then((res) => {
         // 這裡要注意把res.data parse一下,預設是字串
         let parseData = JSON.parse(res.data)
         imgUrls.push(parseData.data) // 圖片地址
       })
     }
  },
  uploadFile: function (filePath) {
    // 返回Promise是為了解決圖片上傳的非同步問題
    return new Promise( (resolve, reject) => {
      wx.uploadFile({
        url: app.globalData.baseUrl + '/file/upload', // 上傳地址
        filePath: filePath,
        name: 'file', // 這裡的具體值,問後端人員
        formData: {},
        header: {
          "Content-Type": "multipart/form-data"
        },
        success: (res) =>{
          resolve(res.data)
        },
        fail:(err) => {
          reject(err)
        }
      })
    })
  }
})

wx.uploadFile()是非同步執行的,但是有了async-await的支援,輕鬆搞定非同步等待的問題。