setTimeout在forEach中不起作用 [英] setTimeout not working inside forEach
问题描述
我有一个forEach调用函数.每次调用之间必须有一个延迟.我已经将它放在forEach中的setTimeout中.第一次等待后不考虑超时.而是等待一次,然后一次运行.我已将超时设置为5秒,并且正在使用控制台进行确认.等待5秒,然后一次将所有foobar控制台日志全部记录.
I have a forEach that calls a function. There needs to be a delay between each time it is called. I've put it inside a setTimeout inside the forEach. It isn't respecting the timeout after the first wait. Instead it is waiting once, then running all at once. I've set the timeout to 5 seconds and I am using a console to confirm. 5 seconds of wait, then several foobar console logs all at once.
为什么会出现这种情况?
var index = 0;
json.objects.forEach(function(obj) {
setTimeout(function(){
console.log('foobar');
self.insertDesignJsonObject(obj, index);
}, 5000);
});
推荐答案
Jason所说的完全正确,但我想我会试一试,以便更好地阐明.
What Jason said is totally correct in his answer but I thought I would give it a shot, to better clarify.
这实际上是一个经典的关闭问题.通常情况如下:
This is actually a classic closure problem. Typically it would look something like:
for(var i = 0; i < 10; i++){
setTimeout(function(){
console.log(i);
},i * 1000)
}
新手希望控制台显示:
0
(0 seconds pass...)
1
(1 second passes...)
2
(etc..)
但是事实并非如此!您实际看到的是数字10
被记录10次(每秒1x)!
But that just isn't the case! What you would actually see is the number 10
getting logged 10 times (1x per second)!
为什么会这样?"好问题.封闭范围.上面的for
循环缺少闭包范围,因为在javascript中,只有函数(lambda)具有闭包范围!
"Why does that happen?" Great question. Closure scope. The for
loop above lacks closure scope because in javascript, only functions (lambdas) have closure scope!
请参阅: https://developer.mozilla.org/zh-美国/docs/Web/JavaScript/关闭
但是!如果您尝试过以下操作,那么您的尝试将获得所需的输出:
However! Your attempt would have achieved the desired output if you had tried this:
json.objects.forEach(function(obj,index,collection) {
setTimeout(function(){
console.log('foobar');
self.insertDesignJsonObject(obj, index);
}, index * 5000);
});
因为您可以访问"closur-ed" index
变量-可以在调用函数(lambda)时将其状态视为期望状态!
Because you have access to the "closur-ed" index
variable - you can rely on its state being the expected state when the function (lambda) is invoked!
其他资源:
http://javascript.info/tutorial/closures
http://code.tutsplus.com/tutorials /closures-front-to-back--net-24869
这篇关于setTimeout在forEach中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!