【问题标题】:JavaScript: Weird behavior in forEach loopJavaScript:forEach 循环中的奇怪行为
【发布时间】:2018-04-21 09:48:31
【问题描述】:

我的代码如下所示:

someArray.forEach(x => {
// do something
console.log(‘calling api for ‘ + x);
callAnHttpApiAsync(...);
sleep(10);
});

http api 调用是异步的(但我不使用任何 await/async 语法)并在 api 发回响应后记录一些内容。发生的情况是 forEach 循环完成,然后我才开始看到记录的响应。我希望在循环结束之前看到一些响应(我尝试增加睡眠量),但无论我等待多长时间或循环多长时间,响应总是在循环结束后记录。我使用节点的睡眠库。我看到这样的东西:

calling api for 1
calling api for 2
calling api for 3
...
calling api for 10000
got response for 1
got response for 2
got response for 3
...
got response for 10000   

我已经通过使用 for-of 和 await/async 解决了这个问题(如果您有更好的想法,请告诉我),但我无法理解这种奇怪行为的原因。为什么我只有在完整循环之后才能得到响应?有任何想法吗?抱歉格式化,但我在移动设备上。

【问题讨论】:

  • 它是异步的,是什么让你认为它会被等待?
  • @AnuragSinghBisht — 什么?编号forEach 是同步的。如果callAnApiAsync 不是,那么在forforEach 循环中没有区别。
  • 您的解决方案是正确的。至少我没有更好的主意。使用带有 for 循环的 async/await 可以解决这个问题。
  • @Quentin 我的意思是 forEach 不会等待您的 async 调用完成。如果您希望async api 完成然后运行下一个循环,则需要使用for 循环。 github.com/babel/babel/issues/909.
  • 当你像forEach这样的同步作业触发所有其他任务时,让它们同步或异步必须等到它完成。这就是这里发生的事情。正如 NPM page 中提到的那样,sleep 函数是同步的在那段时间里什么都没有被执行。

标签: javascript node.js foreach


【解决方案1】:

完全披露:我并不真正了解 node.js,只了解客户端 javascript,但我认为这里的解释也适用。

问题的症结在于“异步”并不意味着“并行”。当您调用异步操作时,它会被放入队列中。当 JSVM 完成执行它当前正在运行的代码(在本例中是包含您的 forEach 的代码)时,它才会执行异步队列中的第一个操作并执行它;然后,当它完成时,它会运行之后的那个,依此类推。 IE。无论您启动多少异步作业,一次只能运行一个。

【讨论】:

    猜你喜欢
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多