背景:
随着业务的增加,前端需要处理多个非依赖(如:ABC三个接口相互没有关联)或依赖(如:B需要拿到A请求后的参数,C需要拿到B请求后的参数)的接口。大多数可能都是依赖接口,为了更优雅的写代码,我们应该使用什么方式去优化呢?
方案:
- ES5的多层嵌套
- ES6的Promise多层then
- ES7的async-await
技术方案:
之前选择的是Promise,当我看着越来越多层的then,心中有万匹草泥马奔过。痛定思痛我准备选择优雅的async-await。
需要解决的问题都有哪些:
- 截止到发文前小程序还不支持ES7的语法,我们到底能不能用?
- 撸的方式又是怎样的?
实践的方式如下:
第一个问题: 虽然小程序不支持,但是我们可以引入js库啊。双手奉上facebook的开源库regenerator 下载'packages/regenerator-runtime'这个路径下的runtime.js,放到自己小程序项目下的utils或者lib文件夹下。总共就23K不要担心包体积的问题。
第二个问题: Async跟Await的用法
Async - 定义异步函数(async function someName(){...})
- 自动把函数转换为 Promise
- 当调用异步函数时,函数返回值会被 resolve 处理
- 异步函数内部可以使用 await
Await - 暂停异步函数的执行 (var result = await someAsyncCall();)
- 当使用在 Promise 前面时,await 等待 Promise 完成,并返回 Promise 的结果
- await 只能和 Promise 一起使用,不能和 callback 一起使用
- await 只能用在 async 函数中
下面直接撸~
// 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)
})
},
})
至此所有问题,基本都已解决。
Demo代码附上,欢迎参考。