2016-11-17 82 views
2

为什么Javascript显示setTimeout函数同步和异步输出?

for(var i = 2;i >= 1;i--) { 
 
    setTimeout(function (i) { 
 
    console.log(i); 
 
    },1000); 
 
    console.log("hii"); 
 
}

此代码给我输出

  • HII

  • HII

  • 不确定

  • 不确定

凡如下格式使用的setTimeout后给出不同的输出

for(var i = 2;i >= 1;i--) { 
 
    setTimeout(print(i),5000); 
 
    console.log("hii"); 
 
} 
 
function print(i) { 
 
    console.log(i); 
 
}

此代码给我输出

  • HII

  • HII

我不明白,为什么在第二种情况下的代码同步执行。

+1

您正在执行'印刷(一)'因为你是循环的回报值。它不返回一个函数(回调)。你需要运行'setTimout(函数名或者匿名函数)'而不是'setTimeout(somefunction())' – mplungjan

回答

5

因为您已经调用了print函数,所以它不会作为回调函数传递。在这种情况下,它将完成print函数的执行,然后将返回值作为第一个参数传递给setTimeout。

这是你正在尝试: -

for(var i = 2;i >= 1;i--) { 
    setTimeout(print(i),5000); 
    console.log("hii"); 
} 
function print(i) { 
    return function(){console.log(i)} 
} 
2

在第一个例子,你传递一个函数,它接受一个参数,i到setTimeout的,但setTimeout的不传递任何参数给这个函数(或任何功能),当它调用它。因此i在该函数中未定义,因此输出undefined

在第二个示例中,您正在调用print并将结果传递给setTimeout。但是print会立即执行,所以这就是为什么在每次迭代之前输出一个数字的原因。

1

for(var i = 2;i >= 1;i--) { 
 
    setTimeout(function (i) { 
 
    console.log(i); 
 
    },1000); 
 
    console.log("hii"); 
 
}

的Javascript具有函数级范围,并且不块级范围。所以,当你调用内部的setTimeout for循环象下面这样:

setTimeout(function (i) { 
     console.log(i); 
     },1000); 

发生的事情是一个局部变量i引入尚未设置为任意值,因此它在JS返回undefined。在你的第二个片段

回调被执行,并显示在屏幕上