ikh*_*vjs 4 javascript promise async-await
在我问这个问题之前,我确实研究了这个问题。
我不明白为什么在下面的示例中,输出在run1
和 中不同run2
。
"use strict";
function sleep(ms) {
return new Promise(resolve =>
setTimeout(() => {
resolve(ms);
}, ms)
);
}
const seconds = [1000, 3000, 2000];
let output1 = 0;
let output2 = 0;
console.log("start");
(async function run1() {
await Promise.all(
seconds.map(async sec => {
output1 = output1 + (await sleep(sec));
})
);
console.log({ output1 });
})();
(async function run2() {
await Promise.all(
seconds.map(async sec => {
const res = await sleep(sec);
output2 = output2 + res;
})
);
console.log({ output2 });
})();
console.log("fin");
Run Code Online (Sandbox Code Playgroud)
对于第一种情况(输出 1),output1
在调用和评估异步函数并等待它之前,“缓存”的当前值。
它或多或少等同于以下内容(执行顺序遵循每个异步函数的睡眠时间):
let old = output1; // 0
output1 = old + 1000;
output1 = old + 2000;
output1 = old + 3000; // 0 + 3000 is the final result
Run Code Online (Sandbox Code Playgroud)
对于第二种情况(输出 2),在缓存当前值之前评估异步函数output2
。您最终会得到所有值的总和。
它或多或少相当于:
let old = output2; // 0
output2 = old + 1000;
old = output2; // 1000
output2 = old + 2000;
old = output2; // 3000
output2 = old + 3000; // 3000 + 3000 is the final result
Run Code Online (Sandbox Code Playgroud)
注意:如果你使用值 [1000, 4000, 2000],你会看到结果是 4000,所以只有中间值被添加到输出中(不是 1000+2000,它也将是 3000 与问题的值)
老实说,我原以为第一种情况的结果是 2000(最后一个值)或不确定的(竞争条件)。显然,JavaScript 如何调度每个异步任务有一些细节。
感谢A_A回答了为什么最终结果是 3000(或 4000,带有更新的值):这是最长的延迟,它将最后执行/完成。
附加说明:我对“缓存”的错误选择似乎引起了混乱。让我试着解释一下:
JavaScript 程序通常从上到下、从左到右进行评估(暂时忽略异步调用)。
let y = 6;
let x = 7;
y = y * x;
Run Code Online (Sandbox Code Playgroud)
JavaScript 运行时将“看到”为:
让我们将其映射到您的第一个示例:
for (let i of [100,300,200])
output1 = output1 + (await sleep(i));
Run Code Online (Sandbox Code Playgroud)
output1
300现在比较第二个例子。评估顺序变为:
for (let i of [100,300,200]) {
const res = await sleep(sec);
output2 = output2 + res;
}
Run Code Online (Sandbox Code Playgroud)
output2
600 归档时间: |
|
查看次数: |
97 次 |
最近记录: |