JavaScript: forEach循环中的奇怪行为

时间:2022-01-21 17:26:14

My code looks like this:

我的代码是这样的:

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

The http api call is async (but I don’t use any await/async syntax) and logs something once the api sends back the response. What happens is that the forEach loop is completed and I start to see the logged responses ONLY AFTER that. I’d expect to see some responses before the loop is over (I tried increasing the amount of sleep), but no matter how long I wait or how long the loop is the responses are logged always after the loop is over. I use a sleep library of node. I see something like this:

http api调用是异步的(但我不使用任何wait/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   

I solved already this issue by using for-of and await/async (please let me know if you have better ideas), but I can’t understand the reason of this weird behavior. Why do I get the responses only after the full loop? Any ideas? Sorry for the formatting but I’m on mobile.

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

1 个解决方案

#1


2  

Full disclosure: I don't really know node.js, only client-side javascript, but I think the explanation works here as well.

完全披露:我真的不知道node。js,只有客户端javascript,但我认为这个解释在这里也适用。

The crux of the issue is that "asynchronous" doesn't mean "parallel". When you call an asynchronous operation, it gets placed in a queue. When the JSVM finishes executing the code it's currently running (which in this case is the code containing your forEach), then and only then does it take the first operation in the async queue and execute it; then, when that finishes, it runs the one after that, and so on. I.e. no matter how many async jobs you start, only one will ever run at a time.

问题的关键在于“异步”并不意味着“并行”。当您调用异步操作时,它将被放置到队列中。当JSVM完成当前运行的代码(在本例中是包含forEach的代码)的执行后,然后只有在异步队列中执行第一个操作并执行它;然后,当它结束时,它运行后面的一个,以此类推。也就是说,无论您启动多少个异步作业,每次只运行一个。

#1


2  

Full disclosure: I don't really know node.js, only client-side javascript, but I think the explanation works here as well.

完全披露:我真的不知道node。js,只有客户端javascript,但我认为这个解释在这里也适用。

The crux of the issue is that "asynchronous" doesn't mean "parallel". When you call an asynchronous operation, it gets placed in a queue. When the JSVM finishes executing the code it's currently running (which in this case is the code containing your forEach), then and only then does it take the first operation in the async queue and execute it; then, when that finishes, it runs the one after that, and so on. I.e. no matter how many async jobs you start, only one will ever run at a time.

问题的关键在于“异步”并不意味着“并行”。当您调用异步操作时,它将被放置到队列中。当JSVM完成当前运行的代码(在本例中是包含forEach的代码)的执行后,然后只有在异步队列中执行第一个操作并执行它;然后,当它结束时,它运行后面的一个,以此类推。也就是说,无论您启动多少个异步作业,每次只运行一个。