Promise的几个重要api
Promise.resolve
// 1. 非Promise对象,非thenable对象 Promise.resolve(1).then(console.log) // 1 // 2. Promise对象成功状态 const p2 = new Promise((resolve) => resolve(2)) Promise.resolve(p2).then(console.log) // 2 // 3. Promise对象失败状态 const p3 = new Promise((_, reject) => reject('err3')) Promise.resolve(p3).catch(console.error) // err3 // 4. thenable对象 const p4 = { then (resolve) { setTimeout(() => resolve(4), 1000) } } Promise.resolve(p4).then(console.log) // 4 // 5. 啥都没传 Promise.resolve().then(console.log) // undefined
Promise.reject
Promise.reject()
方法返回一个带有拒绝原因的Promise
对象。
Promise.reject(new Error('fail')) .then(() => console.log('Resolved'), (err) => console.log('Rejected', err)) // 输出以下内容 // Rejected Error: fail // at <anonymous>:2:16
Promise.all
Promise.all()
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。这个静态方法应该是面试中最常见的啦
const p = Promise.all([p1, p2, p3])
最终p
的状态由p1
、p2
、p3
决定,分成两种情况。
(1)只有p1
、p2
、p3
的状态都变成fulfilled
,p
的状态才会变成fulfilled
,此时p1
、p2
、p3
的返回值组成一个数组,传递给p
的回调函数。
(2)只要p1
、p2
、p3
之中有一个被rejected
,p
的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给p
的回调函数。
const p1 = Promise.resolve(1) const p2 = new Promise((resolve) => { setTimeout(() => resolve(2), 1000) }) const p3 = new Promise((resolve) => { setTimeout(() => resolve(3), 3000) }) const p4 = Promise.reject('err4') const p5 = Promise.reject('err5') // 1. 所有的Promise都成功了 const p11 = Promise.all([ p1, p2, p3 ]) .then(console.log) // [ 1, 2, 3 ] .catch(console.log) // 2. 有一个Promise失败了 const p12 = Promise.all([ p1, p2, p4 ]) .then(console.log) .catch(console.log) // err4 // 3. 有两个Promise失败了,可以看到最终输出的是err4,第一个失败的返回值 const p13 = Promise.all([ p1, p4, p5 ]) .then(console.log) .catch(console.log) // err4
Promise.allSettled
有时候,我们希望等到一组异步操作都结束了,不管每一个操作是成功还是失败,再进行下一步操作。显然
Promise.all
(其只要是一个失败了,结果即进入失败状态)不太适合,所以有了Promise.allSettled
Promise.allSettled()
方法接受一个数组作为参数,数组的每个成员都是一个 Promise 对象,并返回一个新的 Promise 对象。只有等到参数数组的所有 Promise 对象都发生状态变更(不管是fulfilled
还是rejected
),返回的 Promise 对象才会发生状态变更,一旦发生状态变更,状态总是fulfilled
,不会变成rejected
还是以上面的例子为例, 我们看看与Promise.all
有什么不同
const p1 = Promise.resolve(1) const p2 = new Promise((resolve) => { setTimeout(() => resolve(2), 1000) }) const p3 = new Promise((resolve) => { setTimeout(() => resolve(3), 3000) }) const p4 = Promise.reject('err4') const p5 = Promise.reject('err5') // 1. 所有的Promise都成功了 const p11 = Promise.allSettled([ p1, p2, p3 ]) .then((res) => console.log(JSON.stringify(res, null, 2))) // 输出 /* [ { "status": "fulfilled", "value": 1 }, { "status": "fulfilled", "value": 2 }, { "status": "fulfilled", "value": 3 } ] */ // 2. 有一个Promise失败了 const p12 = Promise.allSettled([ p1, p2, p4 ]) .then((res) => console.log(JSON.stringify(res, null, 2))) // 输出 /* [ { "status": "fulfilled", "value": 1 }, { "status": "fulfilled", "value": 2 }, { "status": "rejected", "reason": "err4" } ] */ // 3. 有两个Promise失败了 const p13 = Promise.allSettled([ p1, p4, p5 ]) .then((res) => console.log(JSON.stringify(res, null, 2))) // 输出 /* [ { "status": "fulfilled", "value": 1 }, { "status": "rejected", "reason": "err4" }, { "status": "rejected", "reason": "err5" } ] */
Promise.race
Promise.race()
方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.race([p1, p2, p3])
只要p1
、p2
、p3
之中有一个实例率先改变状态,p
的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p
的回调函数。
const p1 = new Promise((resolve, reject) => { setTimeout(resolve, 500, 1) }) const p2 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 2) }) Promise.race([p1, p2]).then((value) => { console.log(value) // 2 }) Promise.race([p1, p2, 3]).then((value) => { console.log(value) // 3 })