一个 Promise
是一个代理,它代表一个在创建 promise 时不一定已知的值。它允许你将处理程序与异步操作的最终成功值或失败原因关联起来。这使得异步方法可以像同步方法一样返回值:异步方法不会立即返回最终值,而是返回一个 promise,以便在将来的某个时间点提供该值。
一个 Promise
必然处于以下几种状态之一:
- 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
- 已兑现(fulfilled):意味着操作成功完成。
- 已拒绝(rejected):意味着操作失败。
一个待定的 Promise 最终状态可以是已兑现并返回一个值,或者是已拒绝并返回一个原因(错误)。当其中任意一种情况发生时,通过 Promise 的 then
方法串联的处理程序将被调用。如果绑定相应处理程序时 Promise 已经兑现或拒绝,这处理程序将被立即调用,因此在异步操作完成和绑定处理程序之间不存在竞态条件。
如果一个 Promise 已经被兑现或拒绝,即不再处于待定状态,那么则称之为已敲定(settled)。
你还会听到使用已解决(resolved)这个术语来描述 Promise——这意味着该 Promise 已经敲定(settled),或为了匹配另一个 Promise 的最终状态而被“锁定(lock-in)”,进一步解决或拒绝它都没有影响。原始 Promise 提案中的 States and fates 文档包含了更多关于 Promise 术语的细节。在口语中,“已解决”的 Promise 通常等价于“已兑现”的 Promise,但是正如“States and fates”所示,已解决的 Promise 也可以是待定或拒绝的。例如:
JSCopy to Clipboard
new Promise((resolveOuter) => {
resolveOuter(
new Promise((resolveInner) => {
setTimeout(resolveInner, 1000);
}),
);
});
此 Promise 在创建时已经被解决(因为 resolveOuter
是同步调用的),但它是用另一个 Promise 解决的,因此在内部 Promise 兑现的 1 秒之后才会被兑现。在实践中,“解决”过程通常是在幕后完成的,不可观察,只有其兑现或拒绝是可观察的。
Promise 并发
Promise
类提供了四个静态方法来促进异步任务的并发:
在所有传入的 Promise 都被兑现时兑现;在任意一个 Promise 被拒绝时拒绝。
在所有的 Promise 都被敲定时兑现。
在任意一个 Promise 被兑现时兑现;仅在所有的 Promise 都被拒绝时才会拒绝。
在任意一个 Promise 被敲定时敲定。换句话说,在任意一个 Promise 被兑现时兑现;在任意一个的 Promise 被拒绝时拒绝。
所有这些方法都接受一个 Promise(确切地说是 thenable)的可迭代对象,并返回一个新的 Promise。它们都支持子类化,这意味着它们可以在 Promise
的子类上调用,结果将是一个属于子类类型的 Promise。为此,子类的构造函数必须实现与 Promise() 构造函数相同的签名——接受一个以 resolve
和 reject
回调函数作为参数的单个 executor
函数。子类还必须有一个 resolve
静态方法,可以像 Promise.resolve() 一样调用,以将值解析为 Promise。
请注意,JavaScript 的本质上是单线程的,因此在任何时刻,只有一个任务会被执行,尽管控制权可以在不同的 Promise 之间切换,从而使 Promise 的执行看起来是并发的。在 JavaScript 中,并行执行只能通过 worker 线程实现。
构造函数
创建一个新的 Promise
对象。该构造函数主要用于封装还没有添加 promise 支持的函数。
静态属性
返回用于构造从 Promise 方法返回值的构造函数。
静态方法
接受一个 Promise 可迭代对象作为输入,并返回单个 Promise
。返回的 Promise 在所有输入的 Promise 都兑现时(包括传入的可迭代对象为空时)被兑现,其值为一个包含所有兑现值的数组。如果输入的任何 Promise 被拒绝,返回的 Promise 也会被拒绝,并返回第一个拒绝的原因。
接受一个 Promise 可迭代对象作为输入,并返回单个 Promise
。返回的 Promise 在所有输入的 Promise 都敲定时兑现(包括传入的可迭代对象为空时),其值为一个描述每个 Promise 结果的对象数组。
接受一个 Promise 可迭代对象作为输入,并返回单个 Promise
。返回的 Promise 在任何输入的 Promise 兑现时兑现,其值为第一个兑现的值。如果所有输入的 Promise 都被拒绝(包括传入的可迭代对象为空时),返回的 Promise 将以带有一个包含拒绝原因的数组的 AggregateError 拒绝。
接受一个 Promise 可迭代对象作为输入,并返回单个 Promise
。返回的 Promise 与第一个敲定的 Promise 的最终状态保持一致。
返回一个新的 Promise
对象,该对象以给定的原因拒绝。
返回一个新的 Promise
对象,该对象以给定的值兑现。如果值是一个 thenable 对象(即具有 then
方法),则返回的 Promise 对象会“跟随”该 thenable 对象,采用其最终的状态;否则,返回的 Promise 对象会以该值兑现。
通常,如果你不知道一个值是否是 Promise,那么最好使用 Promise.resolve(value) 将其转换成 Promise 对象,并将返回值作为 Promise 来处理。
实例属性
这些属性定义在 Promise.prototype
上,由所有的 Promise
实例共享。
创建实例对象的构造函数。对于 Promise
实例,初始值为 Promise 构造函数。
Promise.prototype[@@toStringTag]
@@toStringTag 属性的初始值为字符串 "Promise"
。该属性用于 Object.prototype.toString()。
实例方法
将一个拒绝处理回调函数附加到 Promise 上,并返回一个新的 Promise,如果回调被调用,则解决为回调的返回值,如果 Promise 被兑现,解决为其原始兑现值。
将一个处理器附加到 Promise 上,并返回一个新的 Promise,当原始 Promise 被解决时解决。无论 Promise 是否被兑现还是被拒绝,处理器都会在 Promise 敲定时被调用。
将一个兑现处理器和拒绝处理器附加到 Promise 上,并返回一个新的 Promise,解决为调用处理器得到的返回值,或者如果 Promise 没有被处理(即相关处理器 onFulfilled
或 onRejected
不是函数),则以原始敲定值解决。