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

javascript的执行流程(同步或异步),javascript,asynchronous,synchronous,Javascript,Asynchronous,Synchronous,有人能解释一下下面的代码和javascript的行为吗 for(var i = 0; i < 5; i++) { setTimeout(function(){ document.write('Iteration ' + i + ' <br>'); },1000); } document.write('DONE!'); for(变量i=0;i

有人能解释一下下面的代码和javascript的行为吗

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

document.write('DONE!');
for(变量i=0;i<5;i++)
{
setTimeout(函数(){
编写('Iteration'+i+'
'); },1000); } 文件。写入('DONE!');
为什么要打印“完成!”第一? 它不应该打印循环的所有值,然后打印“完成”吗

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

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

此代码:

setTimeout(function(){
document.write('Iteration ' + i + ' <br>');
},1000);
setTimeout(函数(){
编写('Iteration'+i+'
'); },1000);
调用函数
setTimeout
,传入您看到的函数。该函数当时未调用。它刚刚创建
setTimeout
稍后将调用它,它的工作也是如此。(当它这样做时,它会吹走文档,因为在页面的主解析完成后调用
document.write
,会隐式地执行
document.open
,从而清除上一个文档。)

下面是这些代码会发生什么:

  • 创建变量
    i
  • 它被设置为
    0
  • 创建一个函数
  • setTimeout
    被调用,函数对象的引用和值
    1000
    一起被传入
  • i
    递增
  • 对于
    i
    的值
    1
    2
    3
    4
    ,重复步骤2至5
  • document.write
    被调用,值为
    'DONE!'
  • 大约一秒钟后,浏览器调用在循环中创建的第一个函数
  • 该函数调用
    document.write
    ,隐式执行
    document.open
    ,将现有文档吹走并替换为
    迭代5
    (是的,实际上是5)
  • 循环中创建的第二个函数运行,再次输出消息
  • 调用其余三个函数,再添加三次消息

  • 我们看到
    迭代5
    五次,而不是
    迭代0
    ,然后是
    迭代1
    等,原因是函数在创建时始终引用变量
    i
    ,而不是它的值,因此它们都会在以后读取它的值,当它们运行时。

    Javascript在正常情况下是同步的,但随着代码更改,有时可以作为异步的,但实际上不会在单独的线程上执行

    好的,如果您想在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!');
    }
    
    length=0;
    对于(变量i=0;i<5;i++)
    {
    设置超时(函数(索引){
    log('Iteration'+index+'
    '); 长度++; 回调(); }(i) ,1000); } 函数回调(){ 如果(长度==5) console.log('DONE!'); }
    我们在这里做的是增加计数器,并尝试在每次增加后调用回调,当计数器达到5时,这意味着调用了所有5个函数,然后我们可以打印
    Done


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

    “完成!”在循环
    完成后打印。流程是先设置5个超时函数,然后按顺序打印完成。函数在间隔后执行,这就是为什么先打印“完成”,但程序的流程是,第一个操作是设置5次超时回调。请参考此线程并检查answer2:@ProblemSolver:不确定您想说什么,但请注意,并非每个人都以相同的顺序看到答案。如果你想引用一个特定的答案,可以使用它下面的“共享”链接来获取指向该特定答案的链接。但是我没有看到上面没有提到的任何相关内容。