为什么使用 for-each 和 for-of 迭代调用异步调用时响应顺序不同?[复制]

Why is the order of response different when calling async calls iteratively using for-each and for-of? [duplicate]

提问人:pythoniesta 提问时间:3/23/2023 最后编辑:pythoniesta 更新时间:3/24/2023 访问量:34

问:

这个问题在这里已经有答案了:
8个月前关闭。

这篇文章在 8 个月前被编辑并提交审核,未能重新打开帖子:

原始关闭原因未解决

我正在尝试在循环中处理 javascript 异步函数。请按照以下代码片段操作

const sleep = async(delay, input) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(input);
    }, delay);
  });
};

const promises = [sleep(500, 1), sleep(1000, 3), sleep(750, 2)];

(async() => {
  console.time('runTime');
  const res1 = [];
  const res2 = [];

  promises.forEach(async(promise) => {
    const res = await promise;
    res1.push(res);
  });

  console.log('logging forEach loop response-1', res1);

  for (const promise of promises) {
    const res = await promise;
    res2.push(res);
  }

  console.log('logging forEach loop response-2', res1);
  console.log('logging for loop response', res2);

  console.timeEnd('runTime');
})();

为上述代码段打印的输出如下

logging forEach loop response-1 []
logging forEach loop response-2 [ 1, 2, 3 ]
logging for loop response [ 1, 3, 2 ]
runTime: 1.011s

为什么输出的顺序在 in 和 in 不同?任何解释都会非常有帮助。forEach response-2for response

编辑:我为之前的vauge问题道歉。但是有两个特别的问题我无法解开

  1. 整个代码段如何需要 ~1 秒才能执行。我理解记录空数组,因为 forEarch 中的回调是异步的,但整个 forEach 不是,并且数组完成后尚未填充。但是在循环的情况下,它不应该花费 ~2.25 秒来执行,因为它在每次迭代中分别等待 0.5 秒、1 秒和 0.75 秒吗?logging forEach loop response-1forEachfor-of

  2. 登录的输出顺序如何按延迟顺序而不是循环顺序排列。是因为在匿名回调的单独实例中创建了,并且每个回调都按延迟顺序解析,因此输出。但如果是这样的话,我的问题 #1 仍然不清楚为什么循环需要 ~1 秒而不是 ~2.25 秒。logging forEach loop response-2for-offorEachfor-of

这篇文章中,我能够部分理解 #2 的原因,但仍然根据我的理解和我所读到的内容,为什么循环的运行时间不是 ~2.25s?for-of

javascript async-await foreach promise for-of-loop

评论

1赞 Bergi 3/24/2023
"for-of循环的情况下,它不应该花费~2.25s来执行,因为它在每次迭代中分别等待0.5s,1s和0.75s吗?- 那是因为你在打电话时开始了所有的 S - 一下子,同时睡觉。promise 代表的是结果,而不是当你这样做时(再次)执行的任务。如果您将调用移动到循环中(例如),超时将是连续的。setTimeoutsleepconst promises = [sleep(500, 1), sleep(1000, 3), sleep(750, 2)];awaitsleepforfor (const t of [500, 1000, 750]) await sleep(t)
1赞 Bergi 3/24/2023
"[res1 的]输出顺序如何按延迟顺序排列?是因为在forEach中创建了一个单独的匿名回调实例,并且每个回调都按延迟顺序[调用]吗?-是的。
0赞 pythoniesta 3/24/2023
非常感谢@Bergi!!,这非常有帮助,尤其是创建带有睡眠的数组的区别,将其称为 Inside Loop。for

答: 暂无答案