这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战
哎呀~开心,终于日更要收工了!
今天接着昨天讲Javascript的Promise同步。
多个Promise同步执行问题
昨天我们阐述了一个Promise与其他代码的同步问题,可以通过以下代码的方式来执行:
new Promise(resolve => {
resolve()
}).then(() => {
// 同步代码
})
那么多个Promise如何保持同步呢,即假如同步代码也是多个Promise呢?
链式结构
首先,我们知道可以按照这样的层次来组织,如下:
promiseA().then(() => {
promiseB.then(() => {
promiseC.then(()=> {
....
})
})
})
这样是符合Promise规则的,但是这样的编码会导致代码的嵌套层次越来越高。
由此便引入了Promise的链式结构,如下:
promiseA().then((xxx) => {xxx})
.then(XXX => {XXX})
.then(xxxx => {
xxxx
})
})
Promise.all
生产环境中有一种场景是: 任务C在任务A,任务B执行完毕后再开始执行。如果我们有Java后台并发编程的经验,应该知道Java有个并发工具类叫:CountDownLatch,通过countDownLatch.await()阻塞线程直到其他所有的前置任务完成后再执行后续任务。
那么Promise这么强大,是否也有同样的类似机制呢?
这便是Promise.all,基础用法:
Promise.all([promiseA, promiseB]).then((values) => {
// 省略的其他任务代码
});
完整的示例大家可以在官方文档中查看。
与Promise.all(xx)方法相似的还有一个Promise.allSettled(),name两者有什么区别呢?
我们来看下面的两端代码:
const promise1 = Promise.resolve(3);
const promise2 = 43;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
Promise.allSettled([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
执行后,结果为:
> Array [3, 43, "foo"]
> Array [3, 43, "foo"] > Array [Object { status: "fulfilled", value: 3 }, Object { status: "fulfilled", value: 43 }, Object { status: "fulfilled", value: "foo" }]
另外,我们修改上述代码中的promise2为:
const promise2 = Promise.reject(43);
即将其中的一个promise修改为失败的状态,会发现输出结果中all不再执行,而allSettled执行结果为:
> Array [Object { status: "fulfilled", value: 3 }, Object { status: "rejected", reason: 43 }, Object { status: "fulfilled", value: "foo" }]
由此可见,all并不能处理拒绝的情况,而且allSettled方法的参数与all也不相同。
Promise的创建方式
之前我一直使用的是new Promise((resolve, reject) => {...})来创建,代码繁琐复杂,这次写文章通过阅读Promise的官方文档,发现其还可以这样用:Promise.resolve(value),例如:
Promise.resolve(43) Promise.resolve(value)
从而简化了Promise需要重叠以及多个Promise的代码复杂度问题。尤其是当我们需要将现有的Promise层级做出更改时尤为方便。