setTimeout 在 forEach 中不起作用 [英] setTimeout not working inside forEach

查看:34
本文介绍了setTimeout 在 forEach 中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个调用函数的 forEach.每次调用之间都需要延迟.我把它放在 forEach 里面的 setTimeout 里面.它不尊重第一次等待后的超时.相反,它等待一次,然后立即运行.我已将超时设置为 5 秒,并且正在使用控制台进行确认.等待 5 秒,然后几个 foobar 控制台同时记录所有日志.

为什么我会出现这种行为?

var index = 0;json.objects.forEach(function(obj) {设置超时(功能(){console.log('foobar');self.insertDesignJsonObject(obj, index);}, 5000);});

解决方案

Jason 在他的回答中说的完全正确,但我想我会试一试,以便更好地澄清.

这实际上是一个经典的闭包问题.通常它看起来像:

for(var i = 0; i <10; i++){设置超时(功能(){控制台日志(i);},我* 1000)}

新手希望控制台显示:

<预><代码>0(0秒过去...)1(1秒过去了……)2(等等..)

但事实并非如此!您实际看到的是 10 被记录 10 次(每秒 1 次)!

为什么会这样?"很好的问题.关闭范围.上面的 for 循环缺少闭包作用域,因为在 javascript 中,只有函数(lambdas)有闭包作用域!

参见:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

但是!如果您尝试过此操作,您的尝试将获得所需的输出:

 json.objects.forEach(function(obj,index,collection) {设置超时(功能(){console.log('foobar');self.insertDesignJsonObject(obj, index);}, 指数 * 5000);});

因为您可以访问Closur-ed"index 变量 - 您可以依赖其状态是调用函数 (lambda) 时的预期状态!

其他资源:

JavaScript 闭包是如何工作的?

http://javascript.info/tutorial/closures

http://code.tutsplus.com/tutorials/closures-front-to-back--net-24869

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.

Why am I getting this behavior?

var index = 0;
json.objects.forEach(function(obj) {
    setTimeout(function(){
        console.log('foobar');
        self.insertDesignJsonObject(obj, index);
    }, 5000);
});

解决方案

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)
}

The novice would expect the console to show:

0
(0 seconds pass...)
1
(1 second passes...)
2
(etc..)

But that just isn't the case! What you would actually see is the number 10 getting logged 10 times (1x per second)!

"Why does that happen?" Great question. Closure scope. The for loop above lacks closure scope because in javascript, only functions (lambdas) have closure scope!

See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

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);
    });

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!

Other Resources:

How do JavaScript closures work?

http://javascript.info/tutorial/closures

http://code.tutsplus.com/tutorials/closures-front-to-back--net-24869

这篇关于setTimeout 在 forEach 中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆