Ale*_*tos 1 javascript node.js es6-promise
这是一个基本问题,但我在任何地方都找不到答案。
我们有两种方法:
// consider someFunction1() and someFunction2() as functions that returns Promises
Approach #1:
return [await someFunction1(), await someFunction2()]
Approach #2:
return await Promise.all([someFunction1(), someFunction2()])
Run Code Online (Sandbox Code Playgroud)
我的团队领导说,这两种方法最终得到了相同的解决方案(两个功能并行执行)。但是,据我所知,第一种方法是await someFunction1()解析然后执行 someFunction2。
所以这就是问题,它真的是一样的吗,还是第二种方法有任何性能改进?非常欢迎提供证明!
不,你不应该接受:
return [await someFunction1(), await someFunction2()];
Run Code Online (Sandbox Code Playgroud)
是相同的:
return await Promise.all([someFunction1(), someFunction2()]);
Run Code Online (Sandbox Code Playgroud)
我还应该指出,await上面的内容return await是不需要的。查看这篇博文以了解更多信息。
他们是不同的!
让我们通过检查这两种替代方案的工作原理来确定差异。
[await someFunction1(), await someFunction2()];
Run Code Online (Sandbox Code Playgroud)
在这里,在async上下文中,我们创建一个数组文字。请注意,someFunction1被调用(每次调用时可能返回一个新承诺的函数)。
因此,当您调用 时someFunction1,会返回一个新的 Promise,然后它“锁定”上下文,async因为前面的await.
简而言之,await someFunction1()“阻止”数组初始化,直到返回的 Promise 得到解决(通过解决或拒绝)。
重复相同的过程至someFunction2。
请注意,在第一种方法中,按顺序等待两个 Promise。因此,与使用的方法没有相似之处Promise.all。让我们看看为什么。
Promise.all([someFunction1(), someFunction2()])
Run Code Online (Sandbox Code Playgroud)
当你申请时Promise.all,它需要一个可迭代的承诺。它会等待您给出的所有承诺进行解析,然后返回一组新的已解析值,但不要等到每个承诺解析后才等待另一个承诺。本质上,它同时等待所有的 Promise,因此它是一种“非顺序”。由于 JavaScript 是单线程的,你无法看出这是“并行”的,但从行为的角度来看却非常相似。
所以,当你传递这个数组时:
[someFunction1(), someFunction2()]
Run Code Online (Sandbox Code Playgroud)
您实际上传递了一组承诺(从函数返回)。就像是:
[Promise<...>, Promise<...>]
Run Code Online (Sandbox Code Playgroud)
请注意,承诺是在外部 Promise.all创建的。
因此,事实上,您正在将一系列承诺传递给Promise.all. 当它们都得到解析时,Promise.all返回解析值的数组。我不会详细解释如何Promise.all工作,为此,我建议您查看文档。
您可以通过在使用await. 就像这样:
const promise1 = someFunction1();
const promise2 = someFunction2();
return [await promise1, await promise2];
Run Code Online (Sandbox Code Playgroud)
promise1在等待时,promise2已在运行(因为它是在第一个 之前创建的await),因此行为类似于Promise.all's。
我的团队领导说,这两种方法最终得到了相同的解决方案(两个功能并行执行)。
这是不正确的。
但是,据我所知,第一种方法是
await someFunction1()解析然后执行 someFunction2。
那是对的。
这是一个演示
const delay = (ms, value) =>
new Promise(resolve => setTimeout(resolve, ms, value));
async function Approach1() {
return [await someFunction1(), await someFunction2()];
}
async function someFunction1() {
const result = await delay(800, "hello");
console.log(result);
return result;
}
async function someFunction2() {
const result = await delay(400, "world");
console.log(result);
return result;
}
async function main() {
const start = new Date();
const result = await Approach1();
const totalTime = new Date() - start;
console.log(`result: ${result}
total time: ${totalTime}`);
}
main();Run Code Online (Sandbox Code Playgroud)
结果是:
hello
world
result: hello,world
total time: 1205
Run Code Online (Sandbox Code Playgroud)
这意味着先someFunction1运行完成,然后再执行。是有顺序的someFunction2
const delay = (ms, value) =>
new Promise(resolve => setTimeout(resolve, ms, value));
async function Approach2() {
return await Promise.all([someFunction1(), someFunction2()]);
}
async function someFunction1() {
const result = await delay(800, "hello");
console.log(result);
return result;
}
async function someFunction2() {
const result = await delay(400, "world");
console.log(result);
return result;
}
async function main() {
const start = new Date();
const result = await Approach2();
const totalTime = new Date() - start;
console.log(`result: ${result}
total time: ${totalTime}`);
}
main();Run Code Online (Sandbox Code Playgroud)
结果是:
world
hello
result: hello,world
total time: 803
Run Code Online (Sandbox Code Playgroud)
这意味着在 之前someFunction2完成。两者是平行的。 someFunction1
| 归档时间: |
|
| 查看次数: |
6006 次 |
| 最近记录: |