意外行为:Javascript、setTimeout()和IIFE
Javascript、事件循环、设置超时、IIFE、闭包 根据以下参考资料,我对以下代码的理解如下: setTimeout()是非阻塞的,由浏览器Web API处理,当计时器完成时,浏览器Web API将回调放在回调队列上。然后,事件循环等待调用堆栈释放,以便依次运行每个回调。setTimeout闭包关闭匿名IIFE,并为每个迭代提供正确的索引值意外行为:Javascript、setTimeout()和IIFE,javascript,closures,settimeout,iife,Javascript,Closures,Settimeout,Iife,Javascript、事件循环、设置超时、IIFE、闭包 根据以下参考资料,我对以下代码的理解如下: setTimeout()是非阻塞的,由浏览器Web API处理,当计时器完成时,浏览器Web API将回调放在回调队列上。然后,事件循环等待调用堆栈释放,以便依次运行每个回调。setTimeout闭包关闭匿名IIFE,并为每个迭代提供正确的索引值 for(var i = 0; i < 3; i++){ (function(index){ setTimeout(fun
for(var i = 0; i < 3; i++){
(function(index){
setTimeout(function(){
console.log(index);
}, 5000);
})(i);
console.log("loop="+i);
}
/*Output in console is
loop=0
loop=1
loop=2
//after 5 seconds
0
1
2
*/
for(变量i=0;i<3;i++){
(功能(索引){
setTimeout(函数(){
控制台日志(索引);
}, 5000);
})(i) );
console.log(“loop=“+i”);
}
/*控制台中的输出是
循环=0
循环=1
循环=2
//5秒后
0
1.
2.
*/
我正在寻找一个关于Chrome中以下代码的解释
for (var i = 0; i < 3; i++) {
setTimeout(
function(index) {
console.log(index);
}(i), 5000
);
console.log("loop="+i);
}
/* Output in console without any delay is:
0
loop=0
1
loop=1
2
loop=2
*/
for(变量i=0;i<3;i++){
设置超时(
函数(索引){
控制台日志(索引);
}(i) ,5000
);
console.log(“loop=“+i”);
}
/*控制台中无任何延迟的输出为:
0
循环=0
1.
循环=1
2.
循环=2
*/
为什么“console.log(index)”会立即执行,不会有5秒的延迟
web API如何将回调作为IIFE执行setTimeout()
是否有回调放入回调队列
事件循环是否将任何回调移动到调用堆栈
还是忽略setTimeout(),并立即在调用堆栈上执行其回调
我查阅过的参考资料: 菲利普·罗伯茨:到底什么是事件循环JSConf欧盟2014 Philip Roberts帮助我陷入2016年的事件循环 调用堆栈和事件循环 在
setTimeout(
function(index) {
console.log(index);
}(i), 5000
);
您正在立即调用传递给setTimeout
的第一个参数。当解释器遇到setTimeout
行时,它首先尝试将其所有参数解析为值。第一个参数是函数调用,因此它调用该函数时期望它将解析为另一个函数,就像我们可以做的那样
setTimeout(makeFn('foo'), 5000);
其中makeFn
返回一个函数
因此,在您的代码中
function(index) {
console.log(index);
}(i)
立即运行,但不返回任何内容-解释器将setTimeout
行解析为
setTimeout(undefined, 5000);
但是undefined
不是一个函数,因此没有任何异步对象排队
这里没有任何IIFE-将整个setTimeout
行放在IIFE中:
for(变量i=0;i<3;i++){
((i)=>{
设置超时(
函数(){
控制台日志(i);
}, 500
);
console.log(“loop=“+i”);
})(i) );
}
在第二个示例中,您没有将函数传递给setTimeout
,而是传递函数调用的结果(在本例中为void)
您可以看到,在这个示例中,您的函数会立即调用,因此,以后无需调用任何东西,控制台会按顺序记录日志
我正在寻找一个关于以下内容的解释
用Chrome编码
for (var i = 0; i < 3; i++) {
setTimeout(
function(index) {
console.log(index);
}(i), 5000
);
console.log("loop="+i);
}
/* Output in console without any delay is:
0
loop=0
1
loop=1
2
loop=2
*/
这是一个匿名函数,立即执行(最后的括号“()”执行该函数):请参见语法function(param){…}()
。因此,对于每个迭代,上面的代码都会立即执行
结果是(如您所见):
这个。方法期望函数(在计时器过期后执行)或代码作为其第一个参数。在这种情况下,您的代码(不是函数)可以立即执行。因此,您可以立即看到结果
5秒的延迟无效,它从未使用过。延迟后没有什么可执行的
Firefox中的效果也一样
您可以尝试匿名函数末尾不带括号的代码,并查看发生了什么:
function(index) {
console.log(index);
}
在这种情况下,该功能将在延迟5秒后执行 作为旁注,如果要将参数传递给setTimeout,则需要将它们放在延迟参数之后,例如setTimeout(函数(索引){/*do stuff*/},5000,i);
function(index) {
console.log(index);
}(i)
0
1
2
function(index) {
console.log(index);
}