关于promise可以先浅显的理解为我去便利蜂买关东煮(返回关东煮就是resolve),如果关东煮没了,我买包子也可以(返回包子就是reject),最后返回的都是吃饱了。
var flag = true;
var promise = new Promise( (resolve, reject) => {
if (flag) {
resolve( '关东煮' )
} else {
reject( '包子' )
}
})
promise
.then( res => {
console.log('购买了:', res)
})
.catch( res => {
console.log('购买了:', res)
})
.finally( () => {
console.log('吃饱啦')
})
Promise 的 描述:
一个
Promise
对象代表一个在这个 promise 被创建出来时不一定已知的值。它让您能够把异步操作最终的成功返回值或者失败原因和相应的处理程序关联起来。 这样使得异步方法可以像同步方法那样返回值:异步方法并不会立即返回最终的值,而是会返回一个 promise,以便在未来某个时候把值交给使用者。
状态:
- 待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
- 已兑现(fulfilled): 意味着操作成功完成。
- 已拒绝(rejected): 意味着操作失败。
待定状态的 Promise 对象要么会通过一个值被兑现(fulfilled),要么会通过一个原因(错误)被拒绝(rejected)。当这些情况之一发生时,我们用 promise 的 then 方法排列起来的相关处理程序就会被调用。如果 promise 在一个相应的处理程序被绑定时就已经被兑现或被拒绝了,那么这个处理程序就会被调用,因此在完成异步操作和绑定处理方法之间不会存在竞争状态。
因为then和catch 方法返回的是promise对象,所以他们可以被方法调用。
promise 代表的是已经正在发生的进程, 而且可以通过回调函数实现链式调用。 如果您想对一个表达式进行惰性求值,就考虑一下使用无参数的"箭头函数": f = () =>
表达式
来创建惰性求值的表达式,使用 f()
求值。
promise的链式回调(亦是 怎么获取到promise的值)
1.then
为 Promise 实例添加状态改变时的回调函数。前面说过,
then
方法的第一个参数是resolved
状态的回调函数,第二个参数(可选)是rejected
状态的回调函数。then
方法返回的是一个新的Promise
实例(注意,不是原来那个Promise
实例)。因此可以采用链式写法,即then
方法后面再调用另一个then
方法。返回的多为new Promise 中 resolve的值,也可返回resolve 和 rejected 的两个值。
单个接受resolve值的写法:
var flag = true;
var promise = new Promise( (resolve, reject) => {
if (flag) {
resolve( '关东煮')
} else {
reject( '包子' )
}
})
promise
.then( res => {
console.log('购买了:', res)
}
)
.catch( res => {
console.log('购买了:', res)
})
.finally( () => {
console.log('吃饱啦')
})
接受resolve值和接受rejected 值 双值的写法:
var flag = true / false;
var promise = new Promise( (resolve, reject) => {
if (flag) {
resolve( '关东煮' )
} else {
reject( '包子' )
}
})
promise
.then(
comments => console.log("resolved: ", comments),
err => console.log("rejected: ", err)
)
.catch( res => {
console.log('购买了:', res)
})
.finally( () => {
console.log('吃饱啦')
})
// 打印 resolve 结果
// 打印 rejected结果
如果使用双值打印,那么会掠过.catch方法。
2.catch
用于指定发生错误时的回调函数。不光是返回rejected,如果运行中抛出错误,也会被
catch
方法捕获。一般来说,不要在then
方法里面定义 Reject 状态的回调函数(即then
的第二个参数),总是使用catch
方法。
var flag = false;
var promise = new Promise( (resolve, reject) => {
if (flag) {
resolve( '关东煮' )
} else {
reject( '包子' )
}
})
promise
.then(
res => {
console.log('购买了:', res)
}
)
.catch( res => {
console.log('购买了:', res)
})
.finally( () => {
console.log('吃饱啦')
})
3.finally
不管Promise对象最后状态如何,都会执行的操作,由ES9 时引用。finally方法中不接受任何参数,也就是说,该方法与resolve和rejected 无关。
var promise = new Promise( (resolve, reject) => {
if (flag) {
resolve( '关东煮' )
} else {
reject( '包子' )
}
})
promise
.then(
res => {
console.log('购买了:', res)
}
)
.catch( res => {
console.log('购买了:', res)
})
.finally( () => {
console.log('吃饱啦')
})
4.all
all方法和then、catch、finally方法都不同的原因是,它是在then、catch、finally方法前执行的,是作用于多个Promise实例,并且将它们包装成新实例的方法。all包装的Promise新实例状态根据作用的多个Promise实例决定。
var flag1 = true;
var flag2 = true;
var promise1 = new Promise( (resolve, reject) => {
if (flag1) {
resolve( 'promise1 成功啦!' )
} else {
reject( 'promise1 失败啦!' )
}
})
var promise2 = new Promise( (resolve, reject) => {
if (flag2) {
resolve( 'promise2 成功啦!' )
} else {
reject( 'promise2 失败啦!' )
}
})
let promise_all = Promise.all([promise1,promise2]).then( res => {
console.log('promise_all:', res)
}).catch( res => {
console.log('promise_all:', res)
}).finally( () => {
console.log('promise_all结束')
})
promise_all的状态由promise1、promise2决定,分成两种情况:
(1)只有promise1、promise2的状态都变成
fulfilled,也可以说是resolve
,promise_all的状态才会变成fulfilled
,此时promise1、promise2的返回值组成一个数组,传递给promise_all的回调函数。(2)只要promise1、promise2之中有一个被
rejected
,promise_all的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给promise_all的回调函数。
var flag1 = true;
var flag2 = false;
var promise1 = new Promise( (resolve, reject) => {
if (flag1) {
resolve( 'promise1 成功啦!' )
} else {
reject( 'promise1 失败啦!' )
}
})
var promise2 = new Promise( (resolve, reject) => {
if (flag2) {
resolve( 'promise2 成功啦!' )
} else {
reject( 'promise2 失败啦!' )
}
})
let promise_all = Promise.all([promise1,promise2]).then( res => {
console.log('promise_all:', res)
}).catch( res => {
console.log('promise_all:', res)
}).finally( () => {
console.log('promise_all结束')
})
4.race
race方法同样也是将多个Promise实例包装成一个新的Promise实例。和all不同的是,race只要有一个实例改变状态,那么新的Promise实例就会改变状态。
var flag1 = true;
var flag2 = true;
var promise1 = new Promise( (resolve, reject) => {
if (flag1) {
setTimeout(() => {
resolve( 'promise1 成功啦!' )
}, 1000);
} else {
reject( 'promise1 失败啦!' )
}
})
var promise2 = new Promise( (resolve, reject) => {
if (flag2) {
resolve( 'promise2 成功啦!' )
} else {
reject( 'promise2 失败啦!' )
}
})
let promise_race = Promise.race([promise1,promise2]).then( res => {
console.log('promise_race:', res)
}).catch( res => {
console.log('promise_race:', res)
}).finally( () => {
console.log('promise_race 结束')
})
5.allSettled
与all一样,allSettled也是接受多个Promise,包装成一个新的Promise实例,都是不管是什么状态都会返回数据。all是只是返回多个Promise的返回值,但是allSettled会返回一个对象里面包括状态和返回值。
var flag3 = true;
var flag4 = false;
var promise3 = new Promise( (resolve, reject) => {
if (flag3) {
resolve( 'promise3 成功啦!' )
} else {
reject( 'promise3 失败啦!' )
}
})
var promise4 = new Promise( (resolve, reject) => {
if (flag4) {
resolve( 'promise4 成功啦!' )
} else {
reject( 'promise4 失败啦!' )
}
})
Promise.allSettled([promise3, promise4]).then(function (res) {
console.log('最后返回的数据:',res);
});
5.any
any 也是接受多个Promise实例,包装成一个新的Promise实例。它的特性是只要多个Promise中有一个是fulfilled状态,那么就都是fulfilled状态;但是,如果都是rejected状态,那么新的Promise实例就会变成rejected状态。any 抛出的错误,不是一个一般的错误,而是一个 AggregateError 实例。它相当于一个数组,每个成员对应一个被rejected的操作所抛出的错误。
var flag5 = true;
var flag6 = false;
var flag7 = false;
var promise5 = new Promise( (resolve, reject) => {
if (flag5) {
resolve( 'promise5 成功啦!' )
} else {
reject( 'promise5 失败啦!' )
}
})
var promise6 = new Promise( (resolve, reject) => {
if (flag6) {
resolve( 'promise6 成功啦!' )
} else {
reject( 'promise6 失败啦!' )
}
})
var promise7 = new Promise( (resolve, reject) => {
if (flag7) {
resolve( 'promise7 成功啦!' )
} else {
reject( 'promise7 失败啦!' )
}
})
Promise.any([ promise5,promise6,promise7]).then(function (res) {
console.log('promise5,promise6,promise7=>最后返回的数据:',res);
});
Promise.any([ promise6,promise7]).catch(function (res) {
console.log('promise6,promise7=>最后返回的数据:',res);
});
捕捉错误时,如果不用try ... catch 结构和 await 命令,可以像下面这样写。
var flag5 = true;
var flag6 = false;
var flag7 = false;
var promise5 = new Promise( (resolve, reject) => {
if (flag5) {
resolve( 'promise5 成功啦!' )
} else {
reject( 'promise5 失败啦!' )
}
})
var promise6 = new Promise( (resolve, reject) => {
if (flag6) {
resolve( 'promise6 成功啦!' )
} else {
reject( 'promise6 失败啦!' )
}
})
var promise7 = new Promise( (resolve, reject) => {
if (flag7) {
resolve( 'promise7 成功啦!' )
} else {
reject( 'promise7 失败啦!' )
}
})
Promise.any([ promise5,promise6,promise7]).then(
(res) => {
console.log('promise5,promise6,promise7=>最后返回的数据=>res:',res);
},
(error) => {
console.log('promise5,promise6,promise7=>最后返回的数据=>error:',error);
}
);
Promise.any([ promise6,promise7]).then(
(res) => {
console.log('promise6,promise7=>最后返回的数据=>res:',res);
},
(error) => {
console.log('promise6,promise7=>最后返回的数据=>error:',error);
}
);
以上,如有错误请多指教。
参考博客:
https://es6.ruanyifeng.com/#docs/promise
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://www.cnblogs.com/dxy9527/p/12505530.html