setTimout()的delay参数如何在循环中工作?

Zac*_*ith 0 javascript settimeout

我有以下代码涉及for循环中的IIFE(立即调用函数表达式).由于打印输出符合预期,因此IIFE功能显然可以获得正确的参数.但我不明白间隔在做什么.据我所知,第一次迭代的间隔应为1秒,然后第二次迭代的间隔为2秒等.

for (var i = 1; i <= 5; i++) {

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

}
Run Code Online (Sandbox Code Playgroud)

我看到i以1秒为间隔打印出1..5.这对我来说很困惑,因为我期望每次迭代时间间隔都会增加.

使用以下代码:

for (var i = 1; i <= 5; i++) {

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

}
Run Code Online (Sandbox Code Playgroud)

我看到i在1秒间隔后立即打印所有值.

在setTimeout函数中发生了什么使它以观察的方式工作?

jfr*_*d00 5

for循环运行到结束.它不会等待setTimeout()来电.因此,当for循环运行时,它会调度setTimeout()从现在开始的1000,2000,3000,4000,5000毫秒的调用.因此,你看到它们都会相隔一秒钟.

在setTimeout函数中发生了什么使它以观察的方式工作?

setTimeout()是一种非阻塞的异步操作.它计划在将来运行,但其周围的其他代码继续运行.然后,在将来的某个时间,计时器将触发并调用回调.

所以,你的代码基本上是这样的:

setTimeout(fn, 1000);
setTimeout(fn, 2000);
setTimeout(fn, 3000);
setTimeout(fn, 4000);
setTimeout(fn, 5000);
Run Code Online (Sandbox Code Playgroud)

它以setTimeout()非阻塞方式一个接一个地运行所有调用.每个setTimeout()函数调用只是在底层系统中注册一个回调和一个时间,然后下一行代码继续执行.然后,在适当的时间过去之后的某个时间,调用回调.所以,希望你能看到所有计时器都计划从现在开始测量他们的时间.因此,你看到它们相隔1秒钟开火.

如果你想要一个异步操作的类比,想象你走动你的房子,你设置五个闹钟,以便在未来一次开始响铃.你设置一个从现在开始一个小时,从现在开始一个两个小时,从现在开始一个三个小时等等......然后,你去做另外的事,做午餐,打扫厨房,割草等等. ..从设置所有时钟开始一小时后,第一个闹钟响起.一个小时之后,下一个开始响铃等等......你可以在他们响铃之前和之后继续做事.在做其他任何事情之前,你不必坐着等待时钟响起.这就是Javascript异步计时器操作的样子.您设置它们然后继续运行其他代码,它们将在未来的预定时间触发.