javascript(同步或异步)的执行流程

flow of execution of javascript(synchronous or asynchronous)

有人可以向我解释以下代码的行为吗 javascript

for(var i = 0; i < 5; i++)
{
    setTimeout(function(){
    document.write('Iteration ' + i + ' <br>');
    },1000);
}

document.write('DONE!');

为什么先打印'DONE!'? 它不应该打印循环的所有值然后打印 'DONE!'?

why does it print 'DONE!' first? Shouldn't it print all values of the loop and then print 'DONE!'?

不,你已经明确告诉它不要这样做;相反,您刚刚创建了五个函数并调用了 setTimeout 五次以将它们提供给浏览器稍后调用。

此代码:

setTimeout(function(){
document.write('Iteration ' + i + ' <br>');
},1000);

调用函数setTimeout,传入你看到的函数。那个函数是 not 当时调用的。它刚刚创建。 setTimeout 以后 会称它为它的工作。 (当它这样做时,它会清除文档,因为在页面的主要解析完成后调用 document.write 会隐式地执行 document.open,这会清除之前的文档。)

下面是这段代码的结果:

  1. 变量 i 已创建。
  2. 设为0
  3. 函数已创建。
  4. 调用
  5. setTimeout 时传入该函数对象的引用以及值 1000.
  6. i递增。
  7. i 的值 1234 重复步骤 2 到 5。
  8. document.write 以值 'DONE!'
  9. 调用
  10. 大约一秒钟后,浏览器调用循环中创建的第一个函数。
  11. 该函数调用 document.write,它隐含地执行 document.open,它会清除现有文档并将其替换为 Iteration 5 <br>(是的,真的是 5)。
  12. 循环中创建的第二个函数是运行,再次输出消息。
  13. 调用其余三个函数,将消息再添加三次。

我们看到 Iteration 5 五次而不是 Iteration 0,然后是 Iteration 1 等的原因是这些函数具有对 变量的持久引用 i,不是创建的时候的值,所以都是后来读取的值,到运行.

的时候

Javascript 在正常情况下是 Synchronous 逐行执行,但是随着代码更改,您有时可以充当异步,但它实际上不会在单独的线程上执行。

好的,如果你想在 Document.write 完成后立即打印 Done 怎么办

length = 0;
for(var i = 0; i < 5; i++)
{
  setTimeout(function(index){
  console.log('Iteration ' + index + ' <br>');
  length++;
  callback();
  }(i),1000);
}

function callback(){
 if(length == 5)
   console.log('DONE!');
}

我们在这里所做的是增加计数器并尝试在每次增加后调用回调,当计数器达到 5 时,这意味着所有 5 个函数都被调用,然后我们能够打印 Done .

附带重要说明,您尝试打印 0、1、2、3、4,但实际上当您 运行 您的代码时,它会给您 5、5、5、,5 , 5 因为你在打印达到 5 时写了 ii 这就是它退出 for 循环的原因,但是你注意到我添加的代码,我通过 i 作为函数的参数,这样它会为我们保存值,当执行函数时它会写入 0, 1, 2, 3, 4