javascript - 一行中的多个等待(嵌套异步调用)
问题描述
我找不到任何关于await
一行中的多个 's 意味着什么或应该如何处理它们的好信息。所以我创建了以下测试代码(在 Node 中执行):
async function resolveAfterNSeconds(n, value) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(value);
}, n*1000);
});
};
async function test(which) {
const start = new Date().getTime();
let result;
switch (which) {
case 1:
result = await resolveAfterNSeconds(10, await resolveAfterNSeconds(2, 'done'));
break;
case 2:
result = await resolveAfterNSeconds(2, await resolveAfterNSeconds(10, 'done'));
break;
case 3:
result = await resolveAfterNSeconds(10, resolveAfterNSeconds(2, 'done'));
break;
case 4:
result = await resolveAfterNSeconds(2, resolveAfterNSeconds(10, 'done'));
break;
case 5:
result = resolveAfterNSeconds(10, await resolveAfterNSeconds(2, 'done'));
break;
case 6:
result = resolveAfterNSeconds(2, await resolveAfterNSeconds(10, 'done'));
break;
}
const end = new Date().getTime();
console.log([which, result, (new Date().getTime()-start)/1000]);
}
test(1); // [1, 'done', 12], as expected
test(2); // [2, 'done', 12], as expected
test(3); // [3, 'done', 10], as expected (kind of)
test(4); // [4, 'done', 10], but expected: [4, Promise, 2]
test(5); // [5, Promise, 2], as expected
test(6); // [6, Promise, 10], as expected
我想我确实理解为什么在案例 3'done'
中返回而不是相应的Promise
- 到那时 2s 超时已经完成(我是对的吗?)。
但是,我不明白案例 4:似乎一await
开始的那个也与 inner 有某种关系Promise
,因为否则,这不应该在 2s 之后Promise
返回(而不是)吗?'done'
但是,如果外部await
实际上也确实与内部相关Promise
,这是否意味着案例 1 和 2 是无意义的,并且应该始终用案例 3 和 4(分别)替换,以便两个或await
更多在一条线上永远有用吗?
解决方案
我想我确实理解为什么在第 3 种情况下,返回“完成”而不是相应的 Promise - 到那时 2 秒超时已经完成(对吗?)。
不,它与案例 4 相同。
但是,我不明白案例 4:似乎一开始的 await 也与内部 Promise 有某种关系,因为否则,这个 Promise 不应该在 2 秒后返回(而不是“完成”)吗?
如果你用另一个 Promise (Y) 解决一个 Promise (X),那么 Promise X采用Promise Y 的状态。
但是,如果外部 await 实际上也确实与内部 Promise 相关,这是否意味着案例 1 和 2 是无意义的,应该始终替换为案例 3 和 4(分别),
不,他们有不同的行为。
如果你await
是一个 promise (Y) 并使用它的解析值作为创建另一个 promise (X) 的函数的参数,那么该函数在 Y 解析之前不会开始运行。
如果您不等待它,那么它将在Y
解决之前开始运行(因此包装在 Promise 中的两个操作可以并行运行)。
推荐阅读
- r - 如何在某些分支上定义某些测试?
- javascript - Google Apps 脚本 - 根据单元格中的值发送电子邮件
- javascript - React JS 从另一个组件渲染组件
- javascript - 隐藏过滤器选项卡上的加载更多按钮,全部(jQuery)除外
- git - 手动合并后如何从拉取请求中规范化合并
- python - ValueError:无法将大小为 78543360 的数组重塑为形状 (51135,4,32,32)
- android - 分页 3:即使存在数据,RecyclerView 仍为空
- regex - 为什么使用捕获组的两个正则表达式的性能差异如此之大?
- r - 我怎样才能转动这个小标题?
- java - 我可以在 scala 项目中生成临时 java 代码吗