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

时间:2015-09-22 10:50:38

标签: javascript asynchronous synchronous

有人可以解释下面代码和javascript的行为

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

document.write('DONE!');

为什么打印&#39; DONE!&#39;第一? 不应该打印循环的所有值,然后打印“完成”!&#39;?

2 个答案:

答案 0 :(得分:5)

  

为什么打印'完成!'第一?它不应该打印循环的所有值,然后打印'完成!'?

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

此代码:

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

调用函数setTimeout,传入您看到的函数。那时候该功能。它刚刚创建。 setTimeout将称之为以后,就像它的工作一样。 (当它发生时,它会吹走文档,因为在页面的主要解析完成之后调用document.write隐式地完成了document.open,这会消除之前的文档。)

所以这就是代码所发生的事情:

  1. 创建变量i
  2. 它设置为0
  3. 创建了一个功能。
  4. 调用
  5. setTimeout时传入函数对象的引用以及值1000
  6. i会增加。
  7. 步骤2到5重复1的值234i
  8. 使用值document.write 调用
  9. 'DONE!'
  10. 大约一秒钟后,浏览器会调用循环中创建的第一个函数。
  11. 该函数调用document.write,它隐含地执行document.open,它会吹走现有文档并将其替换为Iteration 5 <br>(是的,真的是5)。
  12. 运行循环中创建的第二个函数,再次输出消息。
  13. 调用剩余的三个函数,再将消息添加三次。
  14. 我们看到Iteration 5五次而不是Iteration 0,然后是Iteration 1等等,是因为这些函数对变量有持久的引用i,而不是它们在创建时的值,所以它们都会在以后读取它的值,就像它们运行时一样。

答案 1 :(得分:0)

正常的Javascript是Synchronous逐行Exectue,但是随着代码更改,您可以在某个时候执行异步操作,但它实际上不会在单独的线程上执行。

好的,如果您想在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。 / p>

作为一个侧面和重要的注释,你试图打印0,1,2,3,4但实际上当你运行你的代码时它会给你5,5,5,5,5,因为你写{打印时{1}}和i达到5,这就是为什么它会离开for循环,但是你注意到我添加的代码,我将i作为参数传递给函数,以便它将为我们保存值,当执行功能时,它将写入0,1,2,3,4