Promise API 中的静态方法

简介: 捋一捋 Promise 魔法书里的各种静态方法,看看它们有什么用,怎么用,还能给我们带来什么惊喜!🎉

嗨,大家好!这里是道长王jj~ 🎩🧙‍♂️

我们知道 promise 上有许多实例方法,比方说 then()catch() 还有 finally(),就像小积木一样拼起来,变出一串 promise 链!🔗

我们这次捋一捋 Promise 魔法书里的各种静态方法,看看它们有什么用,怎么用,还能给我们带来什么惊喜!🎉

Promise.resolve()

假设你有一个 promise 对象,刚刚被创建出来的时候,最初始会处于 pending 状态,但是,一旦你在执行器函数里面用 resolve() 或者 reject() 时,最终就会为 fulfilledrejectedPromise.resolve() 使我们能够使用我们传递给它的值直接创建一个 fulfilled promise 对象。

const promise = Promise.resolve( "结束咯" );
console.log( promise );

// Promise { <state>: "fulfilled", <value>: "结束咯" }

在上面的示例中, promise 就会直接达到 fulfilled 状态。

有时候咱们就是懒得折腾,不想费尽心思去写个构造函数、搞个执行器函数什么的, Promise.resolve() 非常方便。只需将值作为输入传递给 Promise.resolve() ,即可返回一个 promise 对象。

Promise.reject()

Promise.resolve() 有点像,这次咱们要聊聊 Promise.reject(),这个家伙也是个能把 promise 弄成 rejected 状态🐶,我们只需要丢给他原因即可。

const promise = Promise.reject( "发生错误" );
console.log( promise );

// Promise { <state>: "rejected", <value>: "发生错误" }

在上头的例子里,promise 一溜烟就跑进了狗带状态,根本没进过犹豫不决的 pending 状态。

Promise.all()

大家都知道,我们可以对数组甚至字符串进行循环和迭代。然而,对于 JavaScript 对象,我们无法以相同的方式操作。但是在 ES6 中,我们迎来了可迭代协议,这意味着只要一个对象以特定方式构造,它就可以像数组一样被迭代。当然,我不打算在这篇文章中详细探讨可迭代对象的所有细节📚

好,接下来说说 Promise.all() 吧!为了方便起见,我们只讨论将一系列 promise 作为 Promise.all() 的输入情况。

Promise.all() 会返回一个崭新的 promise。当所有输入的 promise 都变成 resolved 状态时,这个返回的 promise 也会变成 resolved。但如果有任何一个输入的 promise 被 rejected,那么这个返回的 promise 也会被拒绝。这就是 Promise.all() 在管理多个相互依赖的异步操作时显得十分便捷的原因。

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

const promise1 = delay(1000).then(() => 1);
const promise2 = delay(2000).then(() => 2);
const returnedPromise = Promise.all([promise1, promise2]);

console.log("初始化状态:", returnedPromise); // pending

promise1.then(() => {
   
  console.log("promise1执行完后", returnedPromise); // pending
});

promise2.then(() => {
   
  console.log("promise2执行完后:", returnedPromise); // fulfilled ,  [ 1, 2 ] 
});

在上面的示例中,promise1 会在 1 秒后变成 resolved,值为 1。然而,来自 Promise.all()returnedPromise 目前还没有完成。它等待着数组中的 promise2 也变成 resolved。当 promise2 在 2 秒后变成 resolved,值为 2,那么 returnedPromise 也会变成 resolved。此时,returnedPromise 的值是输入的各个 promise 值的数组,对于这个例子来说是 [1, 2]

让我们看一个被拒绝的情况。🙅‍♂️

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

const promise1 = delay(1000).then(() => 1);
const promise2 = delay(2000).catch(() => "出错了");
const promise3 = delay(3000).then(() => 3);

const returnedPromise = Promise.all([promise1, promise2, promise3]);

console.log("初始化状态:", returnedPromise); // pending

promise1.then(() => {
   
  console.log("promise1执行完后:", returnedPromise);// pending
});

promise2.catch(() => {
   
  console.log("promise2执行完后:", returnedPromise); // rejected,  出错了
});

promise3.then(() => {
   
  console.log("promise3执行完后:", returnedPromise); // rejected,  出错了
});

在上面的例子中,promise1 会在 1 秒后变成 resolved。此时,returnedPromise 仍然保持着 pending 状态,因为它在等待 promise2promise3 的状态。但是,promise2 却被拒绝了。这导致 returnedPromise 也被拒绝,拒绝的原因与 promise2 相同。

此外,Promise.all() 不会等待 promise3 的完成。一旦它在输入的 promise 中遇到了拒绝,Promise.all() 就会立即将返回的 promise 拒绝。这也就是为什么我们说在 Promise 的世界里,Promise.all() 会在遇到拒绝的输入 promise 时“短路”。🏃‍♂️

Promise.allSettled()

这个函数与 Promise.all() 非常类似,但它走得更远。实际上,Promise.allSettled() 会等待所有异步操作都结束,这意味着返回的 promise 会等待每个输入的 promise 都被解决。即使其中一个输入的 promise 被拒绝,返回的 promise 仍然会等待其他的 promise 结束,然后再自行结算。这就是为什么 Promise.allSettled() 特别适用于管理多个不相互依赖的异步操作的原因。🕒

Promise.allSettled() 也会接受一个可迭代的变量或数组作为输入,并返回一个崭新的 promise

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

const promise1 = delay(1000).then(() => 1);
const promise2 = delay(2000).catch(() => "出错了");
const promise3 = delay(3000).then(() => 3);

const returnedPromise = Promise.allSettled([promise1, promise2, promise3]);

console.log("初始化状态:", returnedPromise);  // pending 

promise1.then(() => {
   
  console.log("promise1执行完后:", returnedPromise); // pending 
});

promise2.catch(() => {
   
  console.log("promise2执行完后:", returnedPromise); // pending 
});

promise3.then(() => {
   
  console.log("promise3执行完后:", returnedPromise); // fulfilled
  // [
  //  { "status": "fulfilled", "value": 1 },
  //  { "status": "rejected", "reason": "出错了" },
  //  { "status": "fulfilled", "value": 3 }
  // ]
});

在上面的示例中,注意当 promise2 被拒绝时,returnedPromise 并没有被拒绝。相反,它会等待 promise3 完成。当这三个 promise 都结束时,returnedPromise 才会实现。还要注意,returnedPromise 的值与 Promise.all() 的情况不同。这里返回的值不是一个简单的包含每个 resolved promise 值的数组,而是一个对象数组。数组中的每个对象按照相同的顺序表示每个输入 promise 的状态。如果 promise 被 resolved,对象中会有 statusvalue 属性;如果 promise 被 rejected,则包含 status 和拒绝的 reason

所以,在 Promise.allSettled() 中,返回的 promise 总是会被实现。即使所有输入 promise 都被拒绝,返回的 promise 也会通过对象数组来表示每个被拒绝的 promise。

如果我们将一个空数组传递给 Promise.allSettled(),它的行为就类似于 Promise.all(),它会(同步地)返回一个已经实现的 promise,其值是一个空数组。在其他所有情况下,返回的 promise 最初都会是挂起状态,并在异步地完成。🌈

Promise.race()

这个函数的操作正如其名,它把输入的 promise 视为参加一场比赛,首先解决的 promise 就是赢家。在这里,胜利意味着 Promise.race() 不会等待其他 promise 的解决。一旦第一个输入 promise 被解决,返回的 promise 就会立即以与第一个解决的 promise 相同的值实现,或者如果它被拒绝,就会拒绝并具有相同的原因。🏆

Promise.race() 也可以接受一个可迭代变量或数组作为输入,并返回一个崭新的 promise。

const promise1 = Promise.resolve(1);
const promise2 = new Promise(resolve => setTimeout(() => resolve(2), 1000));

const returnedPromise = Promise.race([promise1, promise2]);

promise1.then(() => {
   
  console.log("promise1执行完后:", returnedPromise); // fulfilled, 1
});

在上面的例子中,由于 promise1 已经解决,所以 Promise.race() 不会等待 promise2 完成,returnedPromise 会立即以与 promise1 相同的值实现。

如果我们将上面的例子中的 Promise.resolve() 替换为 Promise.reject(),那么 promise1 将被拒绝,但仍然是第一个解决的输入 promise。因此,returnedPromise 将被拒绝,其拒绝原因与 promise1 相同。

如果我们将一个空数组传递给 Promise.race(),返回的 promise 将永远保持在 pending 状态,因为没有任何输入 promise 会率先解决,也就无法决定返回的 promise 是 resolved 还是 rejected。🚦

Promise.any()

这个函数和 Promise.race() 非常相似,唯一的区别是 Promise.race() 等待第一个输入 promise 解决,而 Promise.any() 则等待第一个输入 promise 被 fulfilled。一旦有输入 promise 被实现,Promise.any() 将不再等待其他 promise 的实现。

返回的 promise 会以与第一个已实现的输入 promise 相同的值实现。与 Promise.race() 不同的是,Promise.any() 会忽略所有被拒绝的输入 promise,它会一直等待,直到第一个 promise 被实现。如果没有任何 promise 被实现,或者所有 promise 都被拒绝,Promise.any() 将抛出一个 AggregateErrorError 的子类),它会将所有单独的错误组合在一起。🌸


🎉 你觉得怎么样?这篇文章可以给你带来帮助吗?当你处于这个阶段时,你发现什么对你帮助最大?如果你有任何疑问或者想进一步讨论相关话题,请随时发表评论分享您的想法,让其他人从中受益。🚀✨

目录
相关文章
|
2月前
|
前端开发 小程序 API
【微信小程序】-- 使用 npm 包 - API Promise化(四十二)
【微信小程序】-- 使用 npm 包 - API Promise化(四十二)
|
6月前
|
小程序 前端开发 API
小程序api封装 promise使用
小程序api封装 promise使用
33 0
|
8月前
|
前端开发 API
Promise 静态 API 的使用方法
Promise 静态 API 的使用方法
39 0
|
9月前
|
前端开发 API
Promise(简介、基本使用、API、手写实现 Promise、async与await)(六)
Promise(简介、基本使用、API、手写实现 Promise、async与await)(六)
|
9月前
|
前端开发 API
Promise(简介、基本使用、API、手写实现 Promise、async与await)(五)
Promise(简介、基本使用、API、手写实现 Promise、async与await)(五)
|
9月前
|
前端开发 API
Promise(简介、基本使用、API、手写实现 Promise、async与await)(四)
Promise(简介、基本使用、API、手写实现 Promise、async与await)(四)
|
9月前
|
前端开发 API
Promise(简介、基本使用、API、手写实现 Promise、async与await)(三)
Promise(简介、基本使用、API、手写实现 Promise、async与await)(三)
|
9月前
|
前端开发 API
Promise(简介、基本使用、API、手写实现 Promise、async与await)(二)
Promise(简介、基本使用、API、手写实现 Promise、async与await)(二)
|
2月前
|
前端开发 JavaScript
如何处理 JavaScript 中的异步操作和 Promise?
如何处理 JavaScript 中的异步操作和 Promise?
16 1
|
2月前
|
前端开发 JavaScript
在JavaScript中,什么是promise、怎么使用promise、怎么手写promise
在JavaScript中,什么是promise、怎么使用promise、怎么手写promise
26 4