我正在尝试并行/并行运行一些异步功能。
我找到了两个解决方案,但不知道它们之间的区别。他们使用Promise.all或附加符号。
如果一个函数引发异常,我也看不到检查结果的意义。
await Promise.all([asyncFunction01(), asyncFunction02()])
const [p1, p2] = await Promise.all([asyncFunction01(), asyncFunction02()])
const p1 = asyncFunction01()
const p2 = asyncFunction02()
await p1 + await p2
const p1 = asyncFunction01()
const p2 = asyncFunction02()
const result = await p1 + await p2
他们对我来说似乎都一样。它们都并行运行,并且在抛出错误的情况下会快速失败。我喜欢第三个选项,因为它看起来更整洁。
那有什么区别?我想念什么吗?
答案 0 :(得分:3)
将两个等待的承诺加在一起可能会或可能不会并行运行,具体取决于您初始化它们的时间。如果您在additional语句本身中初始化它们,它们将顺序运行;第一个运行,然后完成时,第二个运行。参见:
const p1 = () => new Promise((resolve, reject) => {
setTimeout(() => {
console.log('p1')
resolve(200)
}, 5000)
})
const p2 = () => new Promise((resolve, reject) => {
setTimeout(() => {
console.log('p2')
resolve(100)
}, 3000)
})
async function start() {
const result = await p1() + await p2()
console.log(result)
Promise.all([p1(), p2()])
}
start()
如果将等待的承诺加在一起使它们按顺序运行,您会看到p2
在p1
之前完成。事实并非如此。但是,使用Promise.all运行它们时,您会看到p2
首先完成。
正如@Kaiido在评论中指出的那样,OP显示了在等待承诺加总之前开始承诺。在这种情况下,它们将并行运行:
const P1 = () => new Promise((resolve, reject) => {
setTimeout(() => {
console.log('p1')
resolve(200)
}, 5000)
})
const P2 = () => new Promise((resolve, reject) => {
setTimeout(() => {
console.log('p2')
resolve(100)
}, 3000)
})
async function start() {
const p1 = P1()
const p2 = P2()
const result = await p1 + await p2
console.log(result)
}
start()
您会看到p2在p1之前完成。所以您是对的,在功能上没有区别。因此,根据您的用例,它们将完全相同。不过有些想法:
我认为Promise.all更加清晰。您是在向其他开发人员(以及您将来的自己)明确表示要让这些承诺并行运行。
有了Promise.All,您不必为每个Promise创建变量。在许多情况下,Promise.all会更清洁。尽管在您将两个结果加在一起的示例中,使用Promise.all可能不会更干净:
const result = await Promise.all([p1(), p2()]
.then(([r1, r2]) => r1 + r2)
答案 1 :(得分:2)
没有区别!仅有两种替代方法可以实现它。
return5 = async () => new Promise(
resolve => setTimeout(resolve.bind(null, 5),250)
);
return8 = async () => new Promise(
resolve => setTimeout(resolve.bind(null, 8),300)
);
g = async () => {
console.time('await +');
p1a = return5(); // async task started here
p2a = return8(); // async task started here
// waiting for them to all finish here and are printed
console.log(await p1a + await p2a);
console.timeEnd('await +');
console.time('Promise all');
// async tasks started immediately when the promises are passed
// as well as waiting for their completion here
const [p1, p2] = await Promise.all([return5(), return8()]);
// results are here and printed sync
console.log(p1 + p2);
console.timeEnd('Promise all');
}
g();
答案 2 :(得分:1)
创建Promise
对象时(返回new Promise()
时),异步操作已经开始,无论它是await
,它都会成功运行或成功或失败。 -ed是否。
await
-Promise
只是完成这些任务的一种方式:
await
,启动异步操作的代码通常会在异步操作之前完成; await
暂停它,直到异步操作完成,然后再恢复它,从而允许连续执行多个异步操作(在以后的操作取决于必须在其之前运行的操作产生的结果时很有用); 关于异步处理,await p1 + await p2
与await p1; await p2
的结果相同。 p1
承诺等待完成。然后 p2
承诺等待完成。如果p2
在p1
之前完成,则await p2
立即返回。
Promise.all()
的目的不是“并行履行承诺” 。承诺不会运行,它们只是数据(异步代码的结果)。 Promise背后的异步代码可以运行,并且可以“并行”运行,因为这是异步代码的本质。它不需要Promise.all()
来完成。
Promise.all()
的目的是产生一种机制,以轻松await
来处理所有包装的promise,并将所有包装的Promise
的已解析值捕获为单个值(数组) )。
当包装的Promise
对象之一发生故障时,它也会失败。
对于完成/失败部分,await p1 + await p2
大致等于await Promise.all([p1, p2])
。
捕获并返回p1
和p2
的解析值是另一回事。
await p1 + await p2
仅在p1
和p2
的解析值可以使用+
运算符组合的情况下才有效。它不适用于数组和对象。当结果必须以不同的方式组合时,即使使用数字也不起作用。