📕重学JavaScript:Promise 中的静态方法
嗨,大家好!这里是道长王jj~ 🎩🧙♂️
在本次文章中,我们将探讨 Promise API 中的各种静态方法、如何使用它们。
📌Promise.resolve()
我们之前创建的 Promise 对象都是从 pending
状态开始的,然后在执行器函数里用 resolve()
或 reject()
把它们变成 fulfilled
或 rejected
。但是有时候我们想要直接得到一个 fulfilled
的 Promise 对象,怎么办呢?🤔
这时候就可以用 Promise.resolve()
啦!它可以把任何值变成一个已经 fulfilled
的 Promise 对象。👏
var promise = Promise.resolve( " fulfilled" );
console.log( promise );
// Promise { <state>: "fulfilled", <value>: " fulfilled" }
看,上面的例子里, promise
一出生就是 fulfilled
状态,根本不用等待。👌
Promise.resolve()
很方便,因为它让我们不用写那么多构造函数和执行函数的代码,只要给它一个值,它就会给我们一个 Promise 对象。🎁
📌Promise.reject()
有了 Promise.resolve()
,我们可以直接创建一个 fulfilled
的 Promise 对象,那么有没有办法直接创建一个 rejected
的 Promise 对象呢?🤔
当然有啦!就是 Promise.reject()
。它可以把任何设置的值变成一个已经 rejected
的 Promise 对象。😱
var promise = Promise.reject( "出现错误" );
console.log( promise );
/*
Promise {
<state>: "rejected",
<reason>: "出现错误"
}
Uncaught (in promise) 出现错误
*/
看,上面的例子里, promise
一出生就是 rejected
状态,根本不用等待。😢
📌Promise.all()
有时候我们需要等一些 Promise 都完成了才做一些事情,比如买了电影票和爆米花才能看电影。🎬
这时候就可以用 Promise.all()
啦!它可以把一堆 Promise 放在一起,等它们都 fulfilled
了才 fulfilled
。👏
Promise.all()
可以接受一个数组或者一个可迭代的东西,里面放着 1 个或多个 Promise 。
Promise.all()
会返回一个新的 Promise 。如果里面的所有 Promise 都 fulfilled
了,那么这个新的 Promise 也会 fulfilled
。如果里面有任何一个 Promise rejected
了,那么这个新的 Promise 也会 rejected
。😱
这就是为什么 Promise.all()
很适合处理一些需要同时完成的异步操作。🚀
var promise1 = new Promise( (resolve, reject) => {
setTimeout(() => {
resolve( 1 );
}, 1000);
});
var promise2 = new Promise( (resolve, reject) => {
setTimeout(() => {
resolve( 2 );
}, 2000);
});
var returnedPromise = Promise.all([ promise1, promise2 ]);
console.log( "Initially: ", returnedPromise );
promise1.then( value => {
console.log( " 1:", returnedPromise );
});
promise2.then( value => {
console.log( "2: ", returnedPromise );
});
/*
Initially: Promise { <state>: "pending" }
1:Promise { <state>: "pending" }
2: Promise {
<state>: "fulfilled",
<value>: [ 1, 2 ]
}
*/
看,上面的例子里, promise1
用了 1 秒才 fulfilled
,值是“1”。但是 Promise.all()
里的 returnedPromise
还没 fulfilled
。它还在等着它的小伙伴 promise2
。当 promise2
用了 2 秒也 fulfilled
了,值是“2”,那么 returnedPromise
就终于 fulfilled
了。👌
returnedPromise
的值是一个数组,里面放着它的小伙伴们的值,这个例子里就是 [ 1, 2 ]
。
那么如果有一个小伙伴被 rejected
了怎么办呢?🤔
我们来看看下面的例子。
var promise1 = new Promise( (resolve, reject) => {
setTimeout(() => {
resolve( 1 );
}, 1000);
});
var promise2 = new Promise( (resolve, reject) => {
setTimeout(() => {
reject( "出现错误" );
}, 2000);
});
var promise3 = new Promise( (resolve, reject) => {
setTimeout(() => {
resolve( 3 );
}, 3000);
});
var returnedPromise = Promise.all([ promise1, promise2, promise3 ]);
.
console.log( "Initially: ", returnedPromise );
promise1.then( value => {
console.log( " 1:", returnedPromise );
});
promise2.catch( value => {
console.log( "2: ", returnedPromise );
});
promise3.then( value => {
console.log( "3: ", returnedPromise );
});
/*
Initially: Promise { <state>: "pending" }
1:Promise { <state>: "pending" }
2: Promise {
<state>: "rejected",
<reason>: "出现错误"
}
Uncaught (in promise) 出现错误
3: Promise {
<state>: "rejected",
<reason>: "出现错误"
}
*/
看,上面的例子里, promise1
用了 1 秒才 fulfilled
。这时候, returnedPromise
还在等着它的小伙伴们 promise2
和 promise3
。但是 promise2
被 rejected
了。😱
这就让 returnedPromise
也被 rejected
了,原因跟 promise2
一样。
而且, Promise.all()
不会管 promise3
的结果。它只要看到有一个小伙伴被 rejected
了,就马上把自己也变成 rejected
,这就叫做短路。🔥
有一个特别的情况,就是给 Promise.all()
一个空数组。这时候, Promise.all()
会返回一个已经 fulfilled
的 Promise ,值是一个空数组。👍
var returnedPromise = Promise.all( [] );
console.log( returnedPromise );
// Promise { <state>: "fulfilled", <value>: [] }
我们之前看到,返回的 Promise 一般都要等一会儿才 fulfilled
或 rejected
。但是在上面的例子里, returnedPromise
一出生就是 fulfilled
,它不用等待。👌
这是因为它的小伙伴们都是空的,所以它也没什么可等的。😅
这是 Promise.all()
唯一会同步返回一个已经 fulfilled
或 rejected
的 Promise 的情况,其他情况下,它都会返回一个要异步等待的 Promise 。🚀
📌Promise.allSettled()
我们刚刚看到, Promise.all()
会在有一个小伙伴被 rejected
了就短路。但是有时候我们不想这样,我们想要等所有的小伙伴都完成了才做一些事情,不管它们是 fulfilled
还是 rejected
。🤔
这时候就可以用 Promise.allSettled()
啦!它会等所有的异步操作都结束了才结束。👏
就算有一个小伙伴被 rejected
了,它也不会短路,它会继续等着其他的小伙伴。😊
这就是为什么 Promise.allSettled()
很适合处理一些不需要互相依赖的异步操作。🚀
Promise.allSettled()
也可以接受一个数组或者一个可迭代的东西,里面放着 1 个或多个 Promise 。
Promise.allSettled()
也会返回一个新的 Promise 。🎁
var promise1 = new Promise( (resolve, reject) => {
setTimeout(() => {
resolve( 1 );
}, 1000);
});
var promise2 = new Promise( (resolve, reject) => {
setTimeout(() => {
reject( "出现错误" );
}, 2000);
});
var promise3 = new Promise( (resolve, reject) => {
setTimeout(() => {
resolve( 3 );
}, 3000);
});
var returnedPromise = Promise.allSettled([ promise1, promise2, promise3 ]);
console.log( "Initially: ", returnedPromise );
promise1.then( value => {
console.log( " 1:", returnedPromise );
});
promise2.catch( value => {
console.log( "2: ", returnedPromise );
});
promise3.then( value => {
console.log( "3: ", returnedPromise );
});
/*
Initially: Promise { <state>: "pending" }
1:Promise { <state>: "pending" }
2: Promise { <state>: "pending" }
3: Promise {
<state>: "fulfilled",
<value>: [
{ "status": "fulfilled", "value": 1 },
{ "status": "rejected", "reason": "出现错误" },
{ "status": "fulfilled", "value": 3 }
]
}
*/
看,上面的例子里, promise2
被 rejected
了,但是 returnedPromise
没有被 rejected
。它还在等着它的小伙伴 promise3
。当三个小伙伴都结束了, returnedPromise
就终于 fulfilled
了。👌
还有一点不同,就是 returnedPromise
的值不是一个简单的数组,里面放着它的小伙伴们的值。它是一个对象数组,每个对象都表示一个小伙伴的状态。如果小伙伴是 fulfilled
的,那么对象里就有 status
和 value
。如果小伙伴是 rejected
的,那么对象里就有 status
和 reason
。😊
所以,在 Promise.allSettled()
的情况下,返回的 Promise 总是会 fulfilled
。就算所有的小伙伴都被 rejected
了,返回的 Promise 也会通过一个表示每个被 rejected
的小伙伴的对象数组来 fulfilled
。👍
如果我们给 Promise.allSettled()
一个空数组,那么它就跟 Promise.all()
一样,会(同步)返回一个已经 fulfilled
的 Promise ,值是一个空数组。其他情况下,它会返回一个要异步等待的 Promise 。🚀
📌Promise.race()
Promise.race()
的意思就是让一堆 Promise 跑步比赛,谁跑得最快谁就赢了。🏃♂️
这里的赢了是指 Promise.race()
不会管其他的 Promise ,只要有一个 Promise 结束了,它就跟着结束。🏁
如果第一个结束的 Promise 是 fulfilled
的,那么 Promise.race()
也会 fulfilled
,值跟它一样。如果第一个结束的 Promise 是 rejected
的,那么 Promise.race()
也会 rejected
,原因跟它一样。😱
Promise.race()
也可以接受一个数组或者一个可迭代的东西,里面放着 1 个或多个 Promise 。
Promise.race()
也会返回一个新的 Promise 。🎁
var promise1 = Promise.resolve( 1 );
var promise2 = new Promise( (resolve, reject) => {
setTimeout(() => {
resolve( 2 );
}, 1000);
});
var returnedPromise = Promise.race([ promise1, promise2 ]);
promise1.then( value => {
console.log( " 1:", returnedPromise );
});
/*
1:
Promise { <state>: "fulfilled", <value>: 1 }
*/
看,上面的例子里, promise1
先 fulfilled
了,所以 Promise.race()
不会管 promise2
,就跟着 fulfilled
了,值跟它一样。👌
如果我们把上面的例子里的 Promise.resolve()
换成 Promise.reject()
,那么 promise1
就会被 rejected
了,但是它还是第一个结束的。所以 Promise.race()
也会被 rejected
了,原因跟它一样。😢
如果我们给 Promise.race()
一个空数组,那么它会返回一个永远不会结束的 Promise ,因为它没有小伙伴可以跟着。😅
📌Promise.any()
Promise.any()
的意思就是让一堆 Promise 跑步比赛,谁跑得最快且是 fulfilled
的谁就赢了。🏃♀️
这里的赢了是指 Promise.any()
不会管其他的 Promise ,只要有一个 Promise 是 fulfilled
的,它就跟着 fulfilled
。🏁
如果第一个是 fulfilled
的 Promise ,那么 Promise.any()
也会 fulfilled
,值跟它一样。👏
跟 Promise.race()
不一样的是, Promise.any()
不会管被 rejected
的小伙伴,它只在乎 fulfilled
的小伙伴。😊
如果没有一个小伙伴是 fulfilled
的,或者所有的小伙伴都被 rejected
了,那么 Promise.any()
就会抛出一个错误,叫做 AggregateError
,它会把所有的错误都放在一起。😱
🎉 你觉得怎么样?这篇文章可以给你带来帮助吗?当你处于这个阶段时,你发现什么对你帮助最大?如果你有任何疑问或者想进一步讨论相关话题,请随时发表评论分享您的想法,让其他人从中受益。🚀✨