什么是Promise?
Promise 是一种设计模式(1976),前端只是应用了这种设计模式, 而且这种设计模式最初是后端, 而前端借鉴来的;
Promise是异步编程的一种解决方案:- 从语法上讲,promise是一个对象,从它可以获取异步操的消息;
- 从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。
- promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);
- 状态一旦改变,就不会再变。创造promise实例后,它会立即执行。
Promise 的作用
Promise的出现是解决前端异步操作的问题, 在没有 Promise 之前, 可能大部分的时候使用回调的方式来处理异步操作, 并且对于 成功或者失败 取名不是很规范,并且容易出现回调地狱
回调地狱举例
getUser( user =>{
getGroups(user,(groups)=>{
groups.forEach( (g)=>{
g.filter(x => x.ownerId === user.id)
.forEach(x => console.log(x))
})
})
})
在某些情况下,回调嵌套很多时,代码就会非常繁琐,会给我们的编程带来很多的麻烦,这种情况俗称-回调地狱。
这时候Promise就出现了
promise是用来解决三个问题的:
- 规范回调的名称或顺序
- 拒绝回调地狱,让代码可读性更强
- 方便捕获错误
# Promise、Promise.all、Promise.race的用法
Promise初体验
//生成随机数
function rand(m,n){
return Math.ceil(Math.random() * (n-m+1)) + m-1;
}
//点击按钮, 1s 后显示是否中奖(30%概率中奖)若中奖弹出恭喜恭喜,奖品为 10万 RMB 劳斯莱斯优惠券若未中奖弹出 再接再厉
// Promise 形式实现
// resolve 解决 函数类型的数据 reject 拒绝函数类型的数据
const p = new Promise((resolve, reject) => {
setTimeout(() => {
//30%几率成功 1~30设为成功
//获取从1 - 100的一个随机数
let n = rand(1, 100);
//判断
if(n <= 30){
resolve(n); // 将 promise 对象的状态设置为 [成功]
}else(
reject(n); // 将 promise 对象的状态设置为 [失败]
},1000);
//调用 then 方法
//value 本身为值的意思
//reason 本身为理由的意思 (可随意写)
p.then(
(value) => {alert('恭喜恭喜,奖品为 10万 RMB 劳斯莱斯优惠券' + value)},
(reason) => {alert('再接再厉' + reason)}
)
这里 Promise 的使用就很简单, new Promise((resolve, reject) => {}), 四个单词, Promise在这里就声明了 成功是 resolve, 失败是reject, 统一了规范, 而且可以获取异步任务当中成功和失败的结果值
Promise.all使用
Promise.all 需要传入一个数组,数组中的元素都是 Promise 对象。
当这些对象都执行成功时,则 all 对应的 promise 也成功,且执行 then 中的成功回调。
如果有一个失败了,则 all 对应的 promise 失败,且失败时只能获得第一个失败 Promise 的数据。
const p1 = new Promise((resolve, reject) => { resolve('成功了') })
const p2 = Promise.resolve('success')
const p3 = Promise.reject('失败')
Promise.all([p1, p2])
.then((result) => {
console.log(result) //[ "成功了", "success"]
})
.catch((error) => {
//未被调用
})
Promise.all([p1, p3, p2])
.then((result) => {
//未被调用
})
.catch((error) => {
console.log(error) //"失败"
});
Promise.race使用
Promise.race() 里面哪个 Promise 对象最快得到结果,就返回那个结果,不管结果本身是成功状态还是失败状态。
const p1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, "one");
});
const p2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, "two");
});
Promise.race([p1, p2]).then((result) => {
console.log(result); // "two"
// 两个都完成,但 p2 更快
});
const p3 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, "three");
});
const p4 = new Promise(function(resolve, reject) {
setTimeout(reject, 500, "four");
});
Promise.race([p3, p4]).then((result) => {
console.log(result); // "three"
// p3 更快,所以它完成了
}, (error) => {
// 未被调用
});
const p5 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, "five");
});
const p6 = new Promise(function(resolve, reject) {
setTimeout(reject, 100, "six");
});
Promise.race([p5, p6]).then((result) => {
// 未被调用
}, error => {
console.log(error); // "six"
// p6 更快,所以它失败了
});