1.前言
总结前后端交互的几种方式的时候,突然想起来之前小程序用promise封装ajax,简要记录如下
这几天闲来无事又梳理了下promise
2.常规封装
function getApi(url, data, successCB) {
wx.showLoading({
title: '加载中',
})
wx.request({
url: baseUrl + url,
data,
header: {
'content-type': 'application/json' // 默认值
},
success: (res) => {
if (res.code = 200) {
// 回调到组件 ,数据给他
successCB && successCB(res.data)
} else {
wx.showToast({
title: '服务器错误',
icon: 'error',
duration: 2000
})
}
},
fail: (err) => {
wx.showToast({
title: '服务器错误',
icon: 'error',
duration: 2000
})
console.log("错误信息:", err);
},
complete(res) {
// console.log("complete",res);
wx.hideLoading()
// wx.stopPullDownRefresh()
}
})
}
3.promise封装
const getApi = (url, data) => {
wx.showLoading({
title: '加载中',
mask: true
})
// Promise 承诺:处理异步回调 同意 拒绝
return new Promise(function (resolve, reject) {
// 只能走一个 要么同意 要么拒绝
// resolve() 回调then()
// reject() 回调catch()
wx.request({
url: baseUrl + url,
data,
header: {
'content-type': 'application/json' // 默认值
},
success: (res) => {
resolve(res.data)
},
fail: () => {
wx.showToast({
title: '服务器错误',
icon: 'error',
duration: 2000
})
reject("服务器错误,请稍后重试");
},
complete(res) {
// console.log("complete",res);
wx.hideLoading()
// wx.stopPullDownRefresh()
}
})
})
}
4. 调用
var api = require('../../utils/api');
var shopUrl = ""
var data = {}
api.getApi(shopUrl,data).then(()=>{
//处理数据
}).catch(()=>{
//异常处理
wx.showToast({
title: '服务器错误',
icon: 'error',
duration: 2000
})
})
5. why 为什么需要 promise
诞生背景,解决了哪些问题
- js中代码都是单线程 异步执行的.实现异步的方式主要是 回调函数
2
.Promise
是异步编程的一种解决方案,比传统的解决方案更合理和更强大。它由社区最早提出和实现,ES6
将其写进了语言标准,统一了用法,原生提供了Promise
对象
6. 基础概念
简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
从语法上说,
Promise
是一个对象,从它可以获取异步操作的消息。Promise
提供统一的 API,各种异步操作都可以用同样的方法进行处
可以理解为 君子一诺千金,答应的事情,等我这边忙完,一定会给你个答复,不管拒绝还是同意.
7. 核心要点
1.对象的状态不受外界影响。
Promise
对象代表一个异步操作,有三种状态:pending(进行中)
、fulfilled(已成功)
和rejected(已失败)
。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来
它的英语意思就是
“承诺”
,表示其他手段无法改变。
2. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。
Promise
对象的状态改变,只有两种可能:
从pending
变为fulfilled
和
从pending
变为rejected
。
只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为
resolved(已定型
)。如果改变已经发生了,你再对Promise
对象添加回调函数,也会立即得到这个结果。
这与
事件(Event)
完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的
8. 缺点
1.无法取消
Promise
,一旦新建它就会立即执行,无法中途取消。
2.如果不设置回调函数,Promise
内部抛出的错误,不会反应到外部。
3.当处于pending
状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
9. 案例
随机数大于4 你赢了 武林盟主
比多久不清楚,所有用定期模拟,间隔时间也是变量
var test = (resolve, reject) => {
var randomNum = Math.random() * 10
console.log("随机是:", randomNum);
// 比武什么时候结束 是不确定 ,用定时器模拟这个不确定
setTimeout(() => {
if (randomNum > 4) {
resolve("周润发 赌王 赢了")
} else {
reject("周润发 问鼎赌王 失败")
}
}, 1000 * randomNum)
}
外界并不关心你们这场 比武的过程,只关注结果
10. then 你赢的结果
函数执行成功 告诉
Promise
对象:执行then
then
方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例
)。
因此可以采用链式写法,即then
方法后面再调用另一个then
方法。
var p1 = new Promise(test)
var p2 = p1.then(res => {
console.log("成功:", res);
})
Promise
实例具有then
方法,也就是说,then
方法是定义在原型对象Promise.prototype
上的。
它的作用是为
Promise
实例添加状态改变时的回调函数
。前面说过,then方
法的第一个参数是resolved
状态的回调函数,第二个参数是rejected
状态的回调函数,它们都是可选的。
11. catch 你输的结果
函数执行
失败
时,我们告诉Promise
对象: 执行catch
方法
var p3 = p2.catch(err=>{
console.log("失败:",err)
})
Promise.prototype.catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数
12. finally 不管输赢 都会走
finally()
方法用于指定不管Promise
对象最后状态如何,都会执行
的操作。该方法是 ES2018 引入标准的。
var p4 = p3.finally(()=>{
console.log("都会执行")
})
13. 链式写法
new Promise((resolve, reject) => {
var randomNum = Math.random() * 10
console.log("随机是:", randomNum);
// 比武什么时候结束 是不确定 ,用定时器模拟这个不确定
setTimeout(() => {
if (randomNum > 4) {
resolve("周润发 赌王 赢了")
} else {
reject("周润发 问鼎赌王 失败")
}
}, 1000 * randomNum)
}).then(res=>{
console.log("成功:",res);
}).catch(err=>{
console.log("失败:",err);
})
14.原生ajax封装
这里只是简单的例子 ,具体的 请求参数 还需要另做
15. 总结
Promise最大的好处是:
1.在异步执行的流程中, 把执行代码和处理结果的代码清晰地分离了
- 将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数
3.Promise对象提供统一的接口,使得控制异步操作更加容易
参考资料
promise基础
阮一峰-promise
前端请求的5种方式