javascript - 幕后发生了什么?循环中的 Javascript 计时器

标签 javascript timer settimeout

有人可以清楚地分解这里发生的事情吗?

function timerCheck() {
    for(var i=0; i<5; i++) {
        setTimeout(function() {
            console.log("Hello" + i);
        }, 3000);
    }
}

所以你们中的一些人可能知道,调用此函数不会按预期工作。最终会发生的是,这个函数将被一次调用 5 次,每次我都设置为 5。这将是 3 秒后的输出:

Hello5
Hello5
Hello5
Hello5
Hello5

我也明白使用 setInterval 方法是解决此类问题的正确方法,但我很好奇这里的幕后情况。我真的很想了解 Javascript 是如何工作的。请注意,我没有计算机科学背景,只是一个自学成才的编码员。

最佳答案

这可能有助于您更好地了解发生了什么:

function timerCheck() {
    for(var i=0; i<5; i++) {
        console.log("Hi" + i);
        setTimeout(function() {
            console.log("Hello" + i);
        }, 3000);
        console.log("Bye" + i);
    }
}

你会看到

Hi0
Bye0
Hi1
Bye1
Hi2
Bye2
Hi3
Bye3
Hi4
Bye4

立即打印到控制台,因为循环的所有五次迭代都很快完成,然后在五秒钟后您将看到:

Hello5
Hello5
Hello5
Hello5
Hello5

因为超时(几乎在同一时间设置)全部同时发生,并且由于循环已经完成:i == 5 .

这是由 i 的范围引起的.变量 itimerCheck(); 中声明后,范围为 everywhere在 setTimeout 设置的匿名函数中没有本地 i 没有 var i , 和 i不作为函数的参数给出。

您可以使用闭包轻松解决此问题,闭包将返回一个具有 i 的本地副本的函数:

function timerCheck() {
    for(var i=0; i<5; i++) {
        setTimeout((function(loc_i) {
            return function() {
                console.log("Hello" + loc_i);
            };
        })(i), 3000);
    }
}

输出:

Hello0
Hello1
Hello2
Hello3
Hello4

要理解这一点:

(function(loc_i) {
    return function() {
        console.log("Hello" + loc_i);
    };
})(i)

你必须知道在 Javascript 中一个函数是可以立即执行的。 IE。 (function(x){ console.log(x); })('Hi');版画 Hi到控制台。因此,上面的外部函数只接受一个参数(i 的当前值)并将其存储到该函数的一个局部变量中,称为 loc_i。 .该函数立即返回一个打印 "Hello" + loc_i 的新函数到控制台。也就是传入超时的函数。

我希望一切都说得通,如果您对某些事情仍然不清楚,请告诉我。

关于javascript - 幕后发生了什么?循环中的 Javascript 计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8197249/

相关文章:

java - 如何设置 block 超时?

c# - 生成具有动态可变时间间隔的事件

javascript - setTimeout 如何在下面的时钟代码中像 setInterval 一样工作,甚至 setTimeout 只执行一次?

javascript - SetTimeout 不延迟函数调用

javascript - 如何使用 Raphaël 旋转普通图像?

javascript - 对使用 Function 构造函数创建的函数的内部引用

c - C语言中的时间中断

javascript - 检查Javascript中是否存在事件超时

javascript - 如何使用 SimplePagination jquery

javascript - 如何获取二维码以打开 JavaScript 书签