一、静态方法
1.all 方法(有一个失败会立即失败)
Promise.all ()方法,提供了并行执行异步操作的能力,并且在所有异步操作完成之后,统一返回所有结果。接收一个可迭代对象(如数组)作为参数,数组长度取决于 Promise 的个数。
Promise.all()
接收一个Promise[]
,返回一个Promise
实例,当所有的 Promise 执行完毕并且都是fulfilled
时,该实例的状态才会变为fulfilled
,只要队列中有一个实例的状态是rejected
,那么该实例的状态也会变为rejected
如果 Promise 队列中所有的实例状态都是fulfilled
,那么Promise.all()
返回的实例的状态就会变为fulfilled
,并且resolve()
的参数可以是一个数组,按照顺序放置队列中每个 Promise 成功后的结果。
成功的例子:
var promise1 = Promise.resolve(3);
var promise2 = 42;
var promise3 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then(function(values) {
console.log(values); // 输出: [3, 42, 'foo']
});
失败的例子:
// 创建三个Promise,其中一个会失败
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => resolve('Promise 1 resolved'), 1000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => resolve('Promise 2 resolved'), 2000);
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => reject('Promise 3 rejected'), 1500);
});
// 使用Promise.all
Promise.all([promise1, promise2, promise3])
.then(results => {
console.log('All promises resolved:', results);
})
.catch(error => {
console.error('One of the promises rejected:', error);
});
在上述代码中:
promise1
会在 1 秒后解决 (resolved) 并返回'Promise 1 resolved'
。promise2
会在 2 秒后解决 (resolved) 并返回'Promise 2 resolved'
。promise3
会在 1.5 秒后被拒绝 (rejected) 并返回'Promise 3 rejected'
。
由于 promise3
在 1.5 秒后被拒绝,Promise.all
会立即被拒绝,并且 .catch
块中的错误处理程序会捕获到这个拒绝的原因,即 'Promise 3 rejected'
。因此输出将是:
One of the promises rejected: Promise 3 rejected
2.allSettled 方法(即使有失败也要执行完再出结果)
all
方法是有缺陷的,如果在 Promise 队列中有一个状态是 rejected,那么我们就无法获取到其他 fullfilled 以及 pending 的 Promise 实例了。
针对这一情况,在 ES11(ES2020) 中新增了一个 API,Promise.allSettled(),它
接收一个可迭代对象(如数组)作为参数,返回一个新的 Promise 对象。
-
该方法返回的 Promise 实例,会在所有 接收Promise 实例执行完毕后,状态方可变为
fulfilled
,并且只会是fulfilled
-
无论队列中的Promise 实例的状态如何,都能获取到结果
-
打印的结果,会包含状态与值/原因
例子:
const promise1 = Promise.resolve('Success 1');
const promise2 = Promise.reject('Error 2');
const promise3 = new Promise((resolve) => setTimeout(resolve, 100, 'Success 3'));
Promise.allSettled([promise1, promise2, promise3])
.then((results) => results.forEach((result) => console.log(result)));
输出结果会是:
{ status: 'fulfilled', value: 'Success 1' }
{ status: 'rejected', reason: 'Error 2' }
{ status: 'fulfilled', value: 'Success 3' }
3.race 方法(不管成功失败,只要求快)
Promise.race()
同样接收一个可迭代对象(如数组)作为参数,返回一个 Promise 实例。该方法会对队列任务完成情况进行监听,如果某一个任务最先完成fulfilled/rejected
,那么返回的实例的状态也会变成对应的fulfilled/rejected
,同时获取到最先完成的结果。
例子:
var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, 'one');
});
var promise2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then(function(value) {
console.log(value); // 输出: 'two',因为promise2先解决
});
4.any 方法(只要有一个成功就返回)
Promise.any()
是 ES12 新增的特性,和Promise.race()
类似,区别在于:
- any 方法会等待一个
fulfilled
状态,才会决定返回 Promise 实例的状态 - 如果队列中所有的实例都是
rejected
状态,那也需要等到所有执行完毕后才会决定返回的 Promise 实例的状态。// 遇到第一个 fulfilled,就会转变返回的 Promise 实例的状态
// 如果所有的都是 rejected,那么只有所有执行完毕后,返回的 Promise 实例才会转变
// 并且会抛出一个错误:[AggregateError: All promises were rejected]
简单理解来说,Promise.any()
会等待第一个fulfilled
的 Promise ,如果队列中没有fulfilled
,那么就会返回一个错误
它接收一个可迭代对象(如数组)作为参数,返回一个新的 Promise 对象。
例子:
var promise1 = new Promise(function(resolve, reject) {
setTimeout(reject, 500, '被拒绝了');
});
var promise2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, '成功了');
});
var promises = [promise1, promise2];
Promise.any(promises).then(function(value) {
console.log(value); // 输出: '成功了',因为promise2先解决
}).catch(function(error) {
console.log(error); // 永远不会执行,因为至少有一个Promise被解决了
});
5.resolve 方法
Promise.resolve()
相当于new Promise(resolve => { resolve() })
如果传入的值是一个 Promise 对象,它将被原封不动地返回;如果传入的是一个 thenable 对象(拥有 then 方法的对象),Promise.resolve()
会将它转换为 Promise 对象法并立即执行其 then 方法;对于其他值,它会返回一个新的 Promise 对象,状态为 resolved。
resolve 参数形态:
- 参数本身是 Promise
- 参数是原始值/对象
- 参数是一个 thenable
Promise.resolve(42).then(function(value) {
console.log(value); // 输出: 42
});
6.reject 方法
Promise.reject()
相当于创建一个 Promise 实例,并且 rejected 了
注意:与Promise.resolve()
不同的是,Promise.reject()
无论传递什么参数都会原样输出
Promise.reject(new Error('出错了')).catch(function(error) {
console.log(error); // 输出: Error: 出错了
});
二、实例方法
1.then方法
通过then
方法可以对 Promise 中的resolve
进行处理。then
方法的返回值是一个 Promise 实例
同一个 Promise 实例可以调用多个then
方法,当 Promise 中resolve
被回调时,所有 then 方法传入的回调函数都会被调用
如果返回的是普通值,那么这个普通值将作为一个新的 Promise 的resolve
的值
如果返回的是 Promise,那么就可以再次调用then
方法
如果返回的是一个对象,并且该对象实现了 thenable,该 then 函数有两个参数resolve
、reject
,则 resolve 的将会传递给下一个 Promise。
2.catch方法
除了then
方法的第二个参数来捕获reject
错误之外,还可以通过catch
方法,catch 返回一个 Promise
catch
方法也是可以多次调用的,只要 Promise 实例的状态为 rejected,那么就会调用catch
方法
catch 方法也会返回一个Promise
实例,返回值的情况:
- 普通值,将作为
resolve
的参数
3.finally方法
finally 是 ES9(ES2018) 新增的一个特性,无论一个Promise
实例是fulfilled
或rejected
,finally
都会执行。
finally 不接收参数。