- 此问题在此处已有答案**:
Any difference between await Promise.all() and multiple await?(6个答案)
1年前关闭。
这是一个基本的问题,但是我在任何地方都找不到答案。
我们有两种方法:
// consider someFunction1() and someFunction2() as functions that returns Promises
Approach #1:
return [await someFunction1(), await someFunction2()]
Approach #2:
return await Promise.all([someFunction1(), someFunction2()])
我的团队领导说这两种方法最终得到了相同的解决方案(两个函数并行执行),但是,据我所知,第一种方法将await someFunction1()
解析,然后执行someFunction2。
所以这就是问题所在,第二种方法是否真的相同,或者是否有任何性能改进?非常欢迎提供证明!
5条答案
按热度按时间5ktev3wc1#
不,您不应接受:
等同于:
我还应该注意到,上面的
return await
中的await
是不需要的。查看this blog post了解更多信息。他们是不同!
第一种方法(顺序)
让我们通过检查这两个选项中的每一个如何工作来确定差异。
这里,在
async
上下文中,我们创建了一个数组常量。注意,someFunction1
被调用了(一个函数,每次被调用时可能返回一个新的promise)。因此,当您调用
someFunction1
时,将返回一个新的promise,然后它将"锁定"async
上下文,因为前面的await
。简而言之,
await someFunction1()
"阻塞"数组初始化,直到返回的承诺得到解决(通过得到解决或拒绝)。对
someFunction2
重复相同的过程。请注意,在第一种方法中,两个承诺是按顺序等待的,因此与使用
Promise.all
的方法没有相似之处,让我们看看为什么。第二种方法(* 非连续 *)
当你应用
Promise.all
时,它期待一个可迭代的承诺。它等待你给出的所有承诺都被解析,然后返回一个新的解析值数组,但是不要等到每个承诺都被解析了才等待另一个。本质上,它同时等待所有的承诺,所以它是一种"非顺序"。由于JavaScript是单线程的,你不能判断这种"并行",但是从行为的Angular 来看非常相似。因此,当传递此数组时:
你实际上传递了一个promise数组(从函数返回),类似于:
注意,承诺是在**
Promise.all
之外创建的。所以你实际上是在传递一个promise数组给
Promise.all
,当它们都被解析后,Promise.all
返回解析值的数组,我不会详细解释Promise.all
是如何工作的,为此,我建议你去看看documentation。你可以复制这种"非连续"的方法,用
await
在之前**创建承诺。当
promise1
等待时,promise2
已经在运行(因为它是在第一个await
之前创建的),因此其行为与Promise.all
的行为类似。6jjcrrmo2#
我的团队领导说,这两种方法最终得到了相同的解决方案(两个功能并行执行)。
这是不正确的。
但是,据我所知,第一种方法将
await someFunction1()
解析,然后执行someFunction2。这是正确的。
下面是一个演示
方法1:
结果为:
这意味着
someFunction1
* 首先 * 运行完成,然后执行someFunction2
。方法2:
结果为:
这意味着
someFunction2
在someFunction1
之前 * 完成,两者是并行的。kcwpcxri3#
很容易看出区别
第一个命令启动
1
,当1
完成时,它启动2
;第二个命令几乎同时启动3
和4
。dxxyhpgq4#
如果你从一个函数开始,它模拟做一些工作,在工作的各个阶段有输出,但要花一些时间
然后你用第二个类似的方法复制它,你插入你的两个方法,你会看到使用
Promise.all
的方法是并行的,而使用2个await
调用的方法是串行的。平行
系列
两者给予了完全相同的 * 结果 *,但到达那里是非常不同的。
mv1qrgav5#
Promise.all()
的MDN文档指出此方法可用于聚合多个承诺的结果。通常在存在多个相关异步任务(整个代码依赖这些任务成功工作)时使用-在代码继续执行之前,我们希望完成所有这些任务。
虽然它不是显式的,但是您可以等待
Promise.all
跟踪多个承诺,只有当所有承诺都得到解决时,代码才会继续执行。由于
await
的操作方式不同,您提到的在数组中捕获单独异步任务的另一种方法也不相同。await分割执行流,允许异步函数的调用方继续执行。在await延迟异步函数的继续之后,后续语句的执行继续进行。如果此await是其函数执行的最后一个表达式,则通过向函数的调用方返回完成await函数的挂起Promise并继续执行该调用方,继续执行。
所以,每次等待都将暂停执行,然后再继续。不需要演示。