WeChat-SmallProgram:微信小程序中使用Async-await方法异步请求变为同步请求

微信小程序中有些 Api 是异步的,无法直接进行同步处理。例如:wx.requestwx.showToastwx.showLoading 等。如果需要同步处理,可以使用如下方法:

提示:Async-await 方法属于ES7语法,在小程序开发工具中如果勾选es6转es5, 会报错:

ReferenceError: regeneratorRuntime is not defined

需要解决的问题都有哪些:

  1、截止到发文前小程序还不支持ES7的语法,我们到底能不能用?

  2、撸的方式又是怎样的?

实践的方式如下:

第一个问题:

  虽然小程序不支持,但是我们可以引入js库啊。双手奉上 facebook 的开源库 regenerator 下载 'packages/regenerator-runtime' 将这个文件放到自己小程序项目下的 utils 或者 lib 文件夹下。

  总共就23K不要担心包体积的问题。

  然后在使用async-awiat的页面中引入

const regeneratorRuntime = require('../../lib/regenerator-runtime/runtime')

第二个问题:

Async 跟 Await 的用法。

  Async - 定义异步函数(async function someName(){...})

  自动把函数转换为 Promise

  当调用异步函数时,函数返回值会被 resolve 处理

  异步函数内部可以使用 await

Await - 暂停异步函数的执行 (var result = await someAsyncCall();)

  当使用在 Promise 前面时,await 等待 Promise 完成,并返回 Promise 的结果

  await 只能和 Promise 一起使用,不能和 callback 一起使用

  await 只能用在 async 函数中

案例代码(一):

在根目录下新建api文件夹,里面新建index.js

// request get 请求
const getData = (url, param) => {
  return new Promise((resolve, reject) => {
    wx.request({
      url: url,
      method: 'GET',
      data: param,
      success (res) {
        console.log(res)
        resolve(res.data)
      },
      fail (err) {
        console.log(err)
        reject(err)
      }
    })
  })
}

// request post 请求
const postData = (url, param) => {
  return new Promise((resolve, reject) => {
    wx.request({
      url: url,
      method: 'POST',
      data: param,
      success (res) {
        console.log(res)
        resolve(res.data)
      },
      fail (err) {
        console.log(err)
        reject(err)
      }
    })
  })
}

// loading加载提示
const showLoading = () => {
  return new Promise((resolve, reject) => {
    wx.showLoading({
      title: '加载中...',
      mask: true,
      success (res) {
        console.log('显示loading')
        resolve(res)
      },
      fail (err) {
        reject(err)
      }
    })
  })
}

// 关闭loading
const hideLoading = () => {
  return new Promise((resolve) => {
    wx.hideLoading()
    console.log('隐藏loading')
    resolve()
  })
}

module.exports = {
  getData,
  postData,
  showLoading,
  hideLoading
}
index.js

在入口文件 app.js 中引入:

//app.js 
const api = require('./api/index')

App({
  onLaunch: function () {
  
  },
  // 全局数据中暴露api
  globalData: { 
    api
  }
})
app.js

在需要使用api 的页面中处理如下:

const app = getApp()

const api = app.globalData.api
const regeneratorRuntime = require('../../lib/regenerator-runtime/runtime')
Page({

  onLoad() {
    this.init()
  },

  // 初始化
  async init() {
    console.log("日志打印(1)");
    await api.showLoading() // 显示loading

    console.log("日志打印(2)");
    await this.getList() // 请求数据

    console.log("日志打印(3)");
    await api.hideLoading() // 等待请求数据成功后,隐藏loading

    console.log("日志打印(4)");
  },

  // 获取列表
  getList() {
    return new Promise((resolve, reject) => {
      api.getData('http://127.0.0.1:9003/list', {
        token: "043c00e6c7ff021e8cc4d394d3264cb5e8c"
      }).then((res) => {
        this.setData({
          list: res
        })
        console.log("返回数据");
        resolve()
      })
        .catch((err) => {
          reject(err)
        })
    })
  },

})
引用的页面

主要看日志的打印顺序 查看执行流程    自行改动 异步|同步 查看效果。

 

案例代码(二):

// pages/index/index.js

//index.js
import regeneratorRuntime from '../../utils/runtime.js'
const moment = require('../../utils/mp-moment')

//获取应用实例
const app = getApp()

Page({

  /**
   * 页面的初始数据
   */
  data: {

  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    let that = this
    // 同步执行异步函数
    that.testAsync()
    // 异步执行异步函数
    // that.testSync()
  },
  async testAsync() {
    let that = this
    console.log(moment(Date.now()).format('YYYY-MM-DD HH:mm:ss') + ' testAsync start')
    console.log('show loading')

    let resultOne = await that.getValueOne();
    console.log(moment(Date.now()).format('YYYY-MM-DD HH:mm:ss') + resultOne)
    let resultTwo = await that.getValueTwo();
    console.log(moment(Date.now()).format('YYYY-MM-DD HH:mm:ss') + resultTwo)
    console.log('hide loading')
    console.log(moment(Date.now()).format('YYYY-MM-DD HH:mm:ss') + ' testAsync end')
  },
  async testSync() {
    let that = this
    console.log(moment(Date.now()).format('YYYY-MM-DD HH:mm:ss') + ' testSync start')
    console.log('show loading')

    let resultOne = that.getValueOne();
    let resultTwo = that.getValueTwo();


    let results = await Promise.all([resultOne, resultTwo])
    console.log(moment(Date.now()).format('YYYY-MM-DD HH:mm:ss') + results[0])
    console.log(moment(Date.now()).format('YYYY-MM-DD HH:mm:ss') + results[1])

    console.log('hide loading')
    console.log(moment(Date.now()).format('YYYY-MM-DD HH:mm:ss') + ' testSync end')

  },
  getValueOne() {
    let that = this
    let startTime = Date.now()

    return new Promise (function(resolve, reject) {
        setTimeout(function() {
          let endTime = Date.now()
          resolve(' 请求成功 one ' + moment(endTime - startTime) + 'ms')
        }, 1000)
    }) 
  },
  getValueTwo() {
    let that = this
    let startTime = Date.now()

    return new Promise(function (resolve, reject) {
      setTimeout(function () {
        let endTime = Date.now()
        resolve(' 请求成功 two ' + moment(endTime - startTime) + 'ms')
      }, 3000)
    }) 
  },
})

 

posted @ 2020-03-19 16:38  coding++  阅读(866)  评论(0编辑  收藏  举报