Promise

Promise是JavaScript中处理异步操作的一种方式,它可以处于待定、已兑现或已拒绝三种状态之一。Promise.all、.allSettled、.any和.race方法分别用于处理并发任务,当所有、所有敲定、任意一个或第一个任务完成时进行相应操作。Promise的这些特性使得异步编程更加有序和易于管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个 Promise 是一个代理,它代表一个在创建 promise 时不一定已知的值。它允许你将处理程序与异步操作的最终成功值或失败原因关联起来。这使得异步方法可以像同步方法一样返回值:异步方法不会立即返回最终值,而是返回一个 promise,以便在将来的某个时间点提供该值。

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

  • 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled):意味着操作成功完成。
  • 已拒绝(rejected):意味着操作失败。

一个待定的 Promise 最终状态可以是已兑现并返回一个值,或者是已拒绝并返回一个原因(错误)。当其中任意一种情况发生时,通过 Promise 的 then 方法串联的处理程序将被调用。如果绑定相应处理程序时 Promise 已经兑现或拒绝,这处理程序将被立即调用,因此在异步操作完成和绑定处理程序之间不存在竞态条件。

如果一个 Promise 已经被兑现或拒绝,即不再处于待定状态,那么则称之为已敲定(settled)

流程图展示了 Promise 状态在 pending、fulfilled 和 rejected 之间如何通过 then() 和 catch() 处理程序进行转换。一个待定的 Promise 可以变成已兑现或已拒绝的状态。如果 Promise 已经兑现,则会执行“on fulfillment”处理程序(即 then() 方法的第一个参数),并继续执行进一步的异步操作。如果 Promise 被拒绝,则会执行错误处理程序,可以将其作为 then() 方法的第二个参数或 catch() 方法的唯一参数来传递。

你还会听到使用已解决(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.all()

所有传入的 Promise 都被兑现时兑现;在任意一个 Promise 被拒绝时拒绝。

Promise.allSettled()

所有的 Promise 都被敲定时兑现。

Promise.any()

任意一个 Promise 被兑现时兑现;仅在所有的 Promise 都被拒绝时才会拒绝。

Promise.race()

任意一个 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[@@species]

返回用于构造从 Promise 方法返回值的构造函数。

静态方法

Promise.all()

接受一个 Promise 可迭代对象作为输入,并返回单个 Promise。返回的 Promise 在所有输入的 Promise 都兑现时(包括传入的可迭代对象为空时)被兑现,其值为一个包含所有兑现值的数组。如果输入的任何 Promise 被拒绝,返回的 Promise 也会被拒绝,并返回第一个拒绝的原因。

Promise.allSettled()

接受一个 Promise 可迭代对象作为输入,并返回单个 Promise。返回的 Promise 在所有输入的 Promise 都敲定时兑现(包括传入的可迭代对象为空时),其值为一个描述每个 Promise 结果的对象数组。

Promise.any()

接受一个 Promise 可迭代对象作为输入,并返回单个 Promise。返回的 Promise 在任何输入的 Promise 兑现时兑现,其值为第一个兑现的值。如果所有输入的 Promise 都被拒绝(包括传入的可迭代对象为空时),返回的 Promise 将以带有一个包含拒绝原因的数组的 AggregateError 拒绝。

Promise.race()

接受一个 Promise 可迭代对象作为输入,并返回单个 Promise。返回的 Promise 与第一个敲定的 Promise 的最终状态保持一致。

Promise.reject()

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

Promise.resolve()

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

通常,如果你不知道一个值是否是 Promise,那么最好使用 Promise.resolve(value) 将其转换成 Promise 对象,并将返回值作为 Promise 来处理。

实例属性

这些属性定义在 Promise.prototype 上,由所有的 Promise 实例共享。

Promise.prototype.constructor

创建实例对象的构造函数。对于 Promise 实例,初始值为 Promise 构造函数。

Promise.prototype[@@toStringTag]

@@toStringTag 属性的初始值为字符串 "Promise"。该属性用于 Object.prototype.toString()

实例方法

Promise.prototype.catch()

将一个拒绝处理回调函数附加到 Promise 上,并返回一个新的 Promise,如果回调被调用,则解决为回调的返回值,如果 Promise 被兑现,解决为其原始兑现值。

Promise.prototype.finally()

将一个处理器附加到 Promise 上,并返回一个新的 Promise,当原始 Promise 被解决时解决。无论 Promise 是否被兑现还是被拒绝,处理器都会在 Promise 敲定时被调用。

Promise.prototype.then()

将一个兑现处理器和拒绝处理器附加到 Promise 上,并返回一个新的 Promise,解决为调用处理器得到的返回值,或者如果 Promise 没有被处理(即相关处理器 onFulfilled 或 onRejected 不是函数),则以原始敲定值解决。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值