Promise 的概念

一个 Promise 必然处于以下几种状态之一:

  • 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled):意味着操作成功完成。可以用then方法来处理。
  • 已拒绝(rejected):意味着操作失败。可以用catch方法来处理
    如果一个 Promise 已经被兑现或拒绝,即不再处于待定状态,那么则称之为已敲定(settled)。

Promise 基本使用

Promise 成功回调

1
2
3
4
5
6
const promise = new Promise((resolve, reject) => {
// 模拟异步操作
setTimeout(() => {
resolve('成功');
},1000)
});

Promise 失败回调

1
2
3
4
5
6
const promise = new Promise((resolve, reject) => {
// 模拟异步操作
setTimeout(() => {
reject('失败');
},1000)
});

Promise then 方法

then 方法用于指定当 Promise 对象状态变为已兑现(fulfilled)时,所执行的操作。

1
2
3
4
5
6
7
8
9
const promise = new Promise((resolve, reject) => {
// 模拟异步操作
setTimeout(() => {
resolve('成功');
},1000)
});
promise.then((res) => {
console.log(res);
});

Promise catch 方法

catch 方法用于指定当 Promise 对象状态变为已拒绝(rejected)时,所执行的操作。

1
2
3
4
5
6
7
8
9
const promise = new Promise((resolve, reject) => {
// 模拟异步操作
setTimeout(() => {
reject('失败');
},1000)
});
promise.catch((err) => {
console.log(err);
});

Promise finally 方法

finally 方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。

1
2
3
4
5
6
7
8
9
const promise = new Promise((resolve, reject) => {
// 模拟异步操作
setTimeout(() => {
resolve('成功');
},1000)
});
promise.finally(() => {
console.log('finally');
})

Promise 并发和静态方法

Promise 类提供了四个静态方法来促进异步任务的并发:

所有这些方法都接受一个 Promise(确切地说是 thenable)的可迭代对象,并返回一个新的 Promise。它们都支持子类化,这意味着它们可以在 Promise 的子类上调用,结果将是一个属于子类类型的 Promise。为此,子类的构造函数必须实现与 Promise() 构造函数相同的签名——接受一个以 resolve 和 reject 回调函数作为参数的单个 executor 函数。子类还必须有一个 resolve 静态方法,可以像 Promise.resolve() 一样调用,以将值解析为 Promise。

请注意,JavaScript 的本质上是单线程的,因此在任何时刻,只有一个任务会被执行,尽管控制权可以在不同的 Promise 之间切换,从而使 Promise 的执行看起来是并发的。在 JavaScript 中,并行执行只能通过 worker 线程实现。

Promise.all()

仅在 ​所有传入的 Promise 都变为 fulfilled(成功)​​ 时才会返回结果数组。若其中​任意一个 Promise 变为 rejected(失败)​,则立即以该失败原因拒绝。
示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 当所有 Promise 成功时,返回的数组 ​严格按传入顺序排列结果,与完成先后无关:
Promise.all([
Promise.resolve(1),
Promise.resolve(2),
Promise.resolve(3)
]).then(console.log); // 输出 [1, 2, 3]

// 只要有一个 Promise 失败,立即终止并返回 ​首个遇到的错误:
Promise.all([
Promise.resolve(1),
Promise.reject('error'),
Promise.resolve(3) // 此结果不会被处理
]).catch(console.log); // 输出 "error"

Promise.allSettled()

在所有的 Promise 都被敲定时兑现。
示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const p1 = Promise.resolve('A');
const p2 = Promise.reject('Error in B');
const p3 = new Promise(resolve => setTimeout(resolve, 50, 'C'));

Promise.allSettled([p1, p2, p3])
.then(results => {
console.log(results);
/* 输出:
[
{ status: 'fulfilled', value: 'A' },
{ status: 'rejected', reason: 'Error in B' },
{ status: 'fulfilled', value: 'C' }
]
*/
});

Promise.any()

只要传入的 Promise 列表中 ​有任意一个变为 fulfilled(成功)​,Promise.any() 就会立即 ​返回该成功值,并忽略其他所有 Promise 的结果(无论其他 Promise 是成功还是失败)。仅在所有传入的 Promise 都变为 rejected(失败)时,才会返回一个被拒绝的 Promise,并返回该拒绝原因。
示例:

1
2
3
4
5
6
// 示例1:第一个成功值被返回
Promise.any([
Promise.reject('error1'),
Promise.resolve('success'),
Promise.reject('error2')
]).then(console.log); // 输出 "success"

Promise.race()

返回的 Promise 状态由​最先敲定(无论是 fulfilled 还是 rejected)​​ 的 Promise 决定,且 ​立即传递其值或原因。一旦首个 Promise 敲定,其他 Promise 的结果将被完全忽略,即使后续有其他 Promise 完成。
示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 第一个完成的 Promise 是成功
const fastSuccess = Promise.resolve('成功');
const slowError = new Promise((_, reject) =>
setTimeout(reject, 100, '超时错误')
);

Promise.race([fastSuccess, slowError])
.then(result => console.log('结果:', result)) // 输出 "结果: 成功"
.catch(error => console.log('错误:', error));

// 第一个完成的 Promise 是失败
const fastError = Promise.reject('请求失败');
const slowSuccess = new Promise(resolve =>
setTimeout(resolve, 100, '延迟成功')
);

Promise.race([fastError, slowSuccess])
.then(result => console.log('结果:', result))
.catch(error => console.log('错误:', error)); // 输出 "错误: 请求失败"

Promise.resolve()

返回一个新的 Promise 对象,该对象以给定的值兑现。如果值是一个 thenable 对象(即具有 then 方法),则返回的 Promise 对象会“跟随”该 thenable 对象,采用其最终的状态;否则,返回的 Promise 对象会以该值兑现。

Promise.reject()

返回一个新的 Promise 对象,该对象以给定的原因拒绝。