推荐思路:了解 Promise —> 试写 Promise 小例子,将原来的回调函数改为 Promise 形式 —> 项目中实践。
推荐 2 位大神的文章:
阮一峰:https://www.imooc.com/article/20580?block_id=tuijian_wz
http://www.ruanyifeng.com/blog/2015/05/async.html
廖雪峰:廖雪峰官网
读完其一必能对 Promise 有个原理性和功能性了解,其中还包括了很多 demo。
推荐一个讲解async 和 await 以及 promise 与 async/await 执行顺序的面试题:http://www.cnblogs.com/paradise-of-sunshine/p/10136856.html
我在小程序开发中使用 Promise 时,在 .then() 中出错,后来辗转一周,发现是少了个 return,案例如下:
这是我小程序 util.js 封装的请求函数
TC._postAjaxPro = function (url, params) {
return new Promise((resolve, reject) => {
wx.showLoading({
title: '加载中',
mask: true
})
wx.request({
url: TC._url + url,
data: params,
method: 'POST',
header: {
'content-type': 'application/x-www-form-urlencoded'
},
success: (res) => {
console.log(res)
if (res.data.Code == 0 || res.data.code == 0 || res.Code == 0 || res.code == 0) {
resolve(res.data)
} else {
TC._toast(res.data.Msg || res.data.msg || res.Msg || res.msg, 'none')
reject(res.data)
}
},
complete: (res) => {
setTimeout(() => {
wx.hideLoading()
}, 400)
}
})
})
}
这是我小程序详情页的请求函数,调用了上文 util.js 中的函数
写法一:promise.then()
sendMsg() {
let that = this;
wx.showModal({
title: '提示',
content: '订单完成,需要发送短信给客户吗?',
success: (res) => {
if (res.confirm) {
let param = {
OrderId: that.data.OrderId,
Finish: that.data.detailData.Finish
}
util.TC._postAjaxPro('AirPortService/AirPortService.aspx', {
UserId: wx.getStorageSync('LOGIN_DATA').UserId,
ComId: wx.getStorageSync('LOGIN_DATA').ComId,
Action: 'SetOrderFinish',
Param: JSON.stringify(param)
})
.then((resolve) => {
let param2 = {
OrderId: that.data.OrderId
}
return util.TC._postAjaxPro('AirPortService/AirPortService.aspx', {
UserId: wx.getStorageSync('LOGIN_DATA').UserId,
ComId: wx.getStorageSync('LOGIN_DATA').ComId,
Action: 'SendFinishSms',
Param: JSON.stringify(param2)
})
})
.then((resolve) => {
util.TC._toast(resolve.Msg, 'success', 800);
})
}
}
})
},
当时,第一个 .then() 中的 return 没写,发现在第一个 .then() 中 console.log(resolve) 时结果正常显示;而第二个 .then() 中的 console.log(resolve) 时结果为 undefined。这是为什么?
then方法可以接受 2 个回调函数作为参数,第一个回调函数是promise对象的状态变为resolved时调用,第二个回调函数是promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供,这两个函数都接受promise对象传出的值作为参数。 根据这个解释,第一个 .then() 中的参数就是 promise 执行后的结果,作为其参数。而第二个 .then() 中的函数执行完后,运行的结果如果并未 return,此时在外层续用 .then(),就没有结果作为其参数,所以如果这么写就必须 return 上一个 .then() 中的运行结果。
在此有一点很有意思的地方,如果把第一个 .then() 中不 return 运行结果,第二个 .then() 写在第一个 .then() 中,也是可以运行的(目测正常,但这又变成回调地狱了),代码如下:
.then((resolve) => {
let param2 = {
OrderId: that.data.OrderId
}
util.TC._postAjaxPro('AirPortService/AirPortService.aspx', {
UserId: wx.getStorageSync('LOGIN_DATA').UserId,
ComId: wx.getStorageSync('LOGIN_DATA').ComId,
Action: 'SendFinishSms',
Param: JSON.stringify(param2)
})
.then((resolve) => {
util.TC._toast(resolve.Msg, 'success', 800);
})
})
从以上代码可以看出,Promise 就是把每一次回调的结果都 return 出来,作为 .then() 的参数,成为链式操作的。
写法二:async await
在小程序中需要引入 runtime.js 文件:import regeneratorRuntime from './utils/runtime.js';可在 GitHub 上下载
sendMsg() {
let that = this;
wx.showModal({
title: '提示',
content: '订单完成,需要发送短信给客户吗?',
async success(res) {
if (res.confirm) {
let param1 = {
OrderId: that.data.OrderId,
Finish: that.data.detailData.Finish
}
let firstRes = await util.TC._postAjaxPro(
'AirPortService/AirPortService.aspx',
{
UserId: wx.getStorageSync('LOGIN_DATA').UserId,
ComId: wx.getStorageSync('LOGIN_DATA').ComId,
Action: 'SetOrderFinish',
Param: JSON.stringify(param1)
}
)
let param2 = {
OrderId: that.data.OrderId
}
let secondRes = await util.TC._postAjaxPro(
'AirPortService/AirPortService.aspx',
{
UserId: wx.getStorageSync('LOGIN_DATA').UserId,
ComId: wx.getStorageSync('LOGIN_DATA').ComId,
Action: 'SendFinishSms',
Param: JSON.stringify(param2)
}
)
util.TC._toast(secondRes.Msg, 'success', 800);
}
}
})
}
以上代码就是一点经验,如有同行小伙伴发现不合理之处,还望留言指教。路漫漫其修远兮,我们一起去求索0.0