为什么在for循环中的所有其他同步代码之后,仍会运行setTimeout延迟为0的延迟? [英] Why does a setTimeout delay of 0 still run after all other synchronous code in a for loop?

查看:103
本文介绍了为什么在for循环中的所有其他同步代码之后,仍会运行setTimeout延迟为0的延迟?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道已经讨论过该问题的版本,并且我认为这是独一无二的。为什么延迟为0,仍会导致以下行为。

I've know versions of this question has been discussed, and I think this is unique. Why does a delay of 0, still causes the below behavior.

for(var i = 0; i <3; i ++) {
  console.log(i, 'started');
  setTimeout(()=> {
    console.log(i);
  },0)
  console.log(i, 'done');
}

console.log('loop over');

   // 0 started
   // 0 done
   // 1 started
   // 1 done
   // 2 started
   // 2 done
   // loop over
   // 3 3 3 

这里是到目前为止,我认为的内容:

Here is what I think I know so far:

从MDN引用有关堆栈上setTimeouts位置的信息:

Quoted from MDN in respect to setTimeouts position on the stack:


这是因为即使setTimeout的调用被延迟了
零,它仍被放置在队列中并计划在下一个
机会运行;不立即。当前执行的代码必须在执行队列中的函数之前完成
,因此生成的
执行顺序可能与预期的不同。

This is because even though setTimeout was called with a delay of zero, it's placed on a queue and scheduled to run at the next opportunity; not immediately. Currently-executing code must complete before functions on the queue are executed, thus the resulting execution order may not be as expected.

Am我正确地说是for循环,并且任何同步代码都在setTimeout之前放置在调用堆栈中,即使您将延迟设置为0,setTimeout也将始终仅运行for循环完成之后?否则,为什么延迟0仍会导致上述行为?

Am I correct in saying the for-loop and any synchronous code is placed on the call stack before setTimeout, AND even if you set the delay to 0, setTimeout will always run only after the for-loop has completed? Otherwise, why would a delay of 0, still result in the above behavior?

谢谢!

编辑:

在朝着正确的方向开始之后,我发现了一些视频和一个不错的小工具,向您展示了事件循环及其与示例代码的关系。这里是JS运行时模拟器:放大镜

After getting started in the right direction, I found a few videos and a nice little tool that shows you the event loop and how it relates to this example code. Here is the JS runtime simulator: loupe

推荐答案

JavaScript在浏览器和服务器上均作为事件循环运行。运行时会不断轮询事件。事件由用户操作(例如,单击DOM元素x),I / O(数据从I / O或ajax调用返回)以及计时器事件(在这种情况下)组成。 setTimeout(fn,0)只是简单地添加一个事件,该事件至少在经过0毫秒后才由事件循环处理。在处理完当前事件后,它将始终执行。

JavaScript, both in the browser and on the server, runs as an event loop. The runtime is constantly polling for events. Events consist of user actions (e.g. DOM element x was clicked), I/O (data came back from I/O or ajax call), and timer events (in this case). setTimeout(fn, 0) simply adds an event to be processed by the event loop at minimum when 0 milliseconds have elapsed. It will always execute after the current event has been processed.

这篇关于为什么在for循环中的所有其他同步代码之后,仍会运行setTimeout延迟为0的延迟?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆