栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

等待多个并发等待操作

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

等待多个并发等待操作

TL; DR

不要在获得承诺的问题中使用模式,而是分别等待它们;而是使用

Promise.all
(至少现在):

const [value1, value2] = await Promise.all([getValue1Async(), getValue2Async()]);

虽然您的解决方案 确实 并行运行这两个操作,但如果两个诺言都被拒绝,它就无法正确处理拒绝。

细节:

您的解决方案并行运行它们,但始终等待第一个完成,然后再等待第二个。 如果您只想启动它们,并行运行它们,并获得两个结果,那就很好了。
(不,不是,请继续阅读…) 请注意,如果第一个完成(例如)花了五秒钟,而第二个则在一秒钟内失败,那么您的代码将等待整整五秒钟,然后再失败。

遗憾的是,当前

await
没有并行等待的语法,因此您有列出的尴尬或
Promise.all
。(不过,有过
await.all
类似的讨论;也许有一天。)

Promise.all
版本是:

const [value1, value2] = await Promise.all([getValue1Async(), getValue2Async()]);

…更加简洁,如果第二个操作很快失败,也不会等待第一个操作完成(例如,在我上面的五秒/一秒示例中,上面的操作将在一秒钟内拒绝,而不是等待五个)
。另请注意,使用原始代码,如果第二个承诺在第一个承诺解决之前被拒绝,您很可能在控制台中收到“未处理的拒绝”错误您目前使用Chrome v61;
更新:更新的 版本具有更有趣的行为,尽管该错误可以说是虚假的(因为您 这样做
,最终可以处理拒绝,因为该代码显然在一个

async
函数¹中,因此该函数将钩住拒绝并使其承诺与它一起被拒绝 **更新:
再次,[更改]。但是,如果两个诺言都被拒绝,您将得到真正的未处理的拒绝错误,因为控制流永远不会到达
const value2 = await p2;
,因此永远不会处理p2拒绝。

未处理的拒绝是Bad Thing™(以至于很快,Node.js就会在真正未处理的拒绝上终止流程,就像未处理的异常一样-
因为它们就是这样),因此最好避免“先得到承诺

await
”。问题中的模式。

这是一个故障情况下时间差异的示例(使用500ms和100ms而不是5秒和1秒),还可能是虚假的未处理拒绝错误(打开 真实的 浏览器控制台查看):

const getValue1Async = () => {  return new Promise(resolve => {    setTimeout(resolve, 500, "value1");  });};const getValue2Async = () => {  return new Promise((resolve, reject) => {    setTimeout(reject, 100, "error");  });};// This waits the full 500ms before failing, because it waits// on p1, then on p2(async () => {  try {    console.time("separate");    const p1 = getValue1Async();    const p2 = getValue2Async();    const value1 = await p1;    const value2 = await p2;  } catch (e) {    console.error(e);  }  console.timeEnd("separate");})();// This fails after just 100ms, because it doesn't wait for p1// to finish first, it rejects as soon as p2 rejectssetTimeout(async () => {  try {    console.time("Promise.all");    const [value1, value2] = await Promise.all([getValue1Async(), getValue2Async()]);  } catch (e) {    console.timeEnd("Promise.all", e);  }}, 1000);Open the real browser console to see the unhandled rejection error.

在这里,我们同时拒绝

p1
p2
,从而导致以下错误
p2

const getValue1Async = () => {  return new Promise((resolve, reject) => {    setTimeout(reject, 500, "error1");  });};const getValue2Async = () => {  return new Promise((resolve, reject) => {    setTimeout(reject, 100, "error2");  });};// This waits the full 500ms before failing, because it waits// on p1, then on p2(async () => {  try {    console.time("separate");    const p1 = getValue1Async();    const p2 = getValue2Async();    const value1 = await p1;    const value2 = await p2;  } catch (e) {    console.error(e);  }  console.timeEnd("separate");})();// This fails after just 100ms, because it doesn't wait for p1// to finish first, it rejects as soon as p2 rejectssetTimeout(async () => {  try {    console.time("Promise.all");    const [value1, value2] = await Promise.all([getValue1Async(), getValue2Async()]);  } catch (e) {    console.timeEnd("Promise.all", e);  }}, 1000);Open the real browser console to see the unhandled rejection error.

在评论中,您询问:

附带问题:以下部队是否会同时等待(并丢弃结果)

await p1 && await p2

关于承诺拒绝的问题与您的原始代码存在相同的问题:

p1
即使
p2
更早拒绝,它也会等到解决为止。如果在解决之前拒绝,则可能会产生可能是虚假的(
update:
或临时未处理的拒绝错误;并且如果和都拒绝,则会生成真正的未处理拒绝错误(因为从未处理过拒绝)。
p2``p1``p1``p2``p2

p1
解决和
p2
拒绝的情况如下:

const getValue1Async = () => {  return new Promise(resolve => {    setTimeout(resolve, 500, false);  });};const getValue2Async = () => {  return new Promise((resolve, reject) => {    setTimeout(reject, 100, "error");  });};(async () => {  try {    const p1 = getValue1Async();    const p2 = getValue2Async();    console.log("waiting");    await p1 && await p2;  } catch (e) {    console.error(e);  }  console.log("done waiting");})();Look in the real console (for the unhandled rejection error).

…而且两者都拒绝:

const getValue1Async = () => {  return new Promise((resolve, reject) => {    setTimeout(reject, 500, "error1");  });};const getValue2Async = () => {  return new Promise((resolve, reject) => {    setTimeout(reject, 100, "error2");  });};(async () => {  try {    const p1 = getValue1Async();    const p2 = getValue2Async();    console.log("waiting");    await p1 && await p2;  } catch (e) {    console.error(e);  }  console.log("done waiting");})();Look in the real console (for the unhandled rejection error).

¹ _“
…此代码显然在

async
函数中…”_在2017年编写此问题和答案时确实如此。从那以后,高层
await
发生了/正在发生。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/411352.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号