为什么为同一函数调用window.setTimeout不会引入无限循环

Why calling of window.setTimeout for the same function doesn't introduce infinite loop?

本文关键字:无限循环 setTimeout window 函数调用 为什么      更新时间:2023-09-26

我看到了以下代码:

class MasterControlPanel {
    private sensors: Sensor[] = [];
    constructor() {
        // Instantiating the delegate HeatSensor
        this.sensors.push(new HeatSensor(this));
    }
    start() {
        for (var i= 0; i < this.sensors.length; i++) {
            // Calling the delegate
            this.sensors[i].check();
        }
        window.setTimeout(() => this.start(), 1000);
    }
    startAlarm(message: string) {
        console.log('Alarm! ' + message);
    }
}
var cp = new MasterControlPanel();
cp.start();

为什么window.setTimeout(() => this.start(), 1000);不引入无限循环?

根据我的理解,cp.start()将首先迭代sensors内部的每个sensor,然后调用window.setTimeout,而又在第二次延迟后再次调用1 start

参考:示例 3-3。Pro TypeScript 中的委派:应用程序规模的 JavaScript 开发

简而言之,它不会引入无限循环,因为 setTimeout 不会阻塞。 相反,你给它执行的函数 (( => this.start(( 被添加到队列中,并在 1 秒后执行。 start 方法在调用 window.setTimeout 后返回,因此不会在命令式意义上导致无限循环。 大多数情况下,代码将处于等待状态,直到下一个计时器出现。

代码无限调度计时器来调用 start 方法也是正确的,但它不是一个无限循环,因为它将控制权返回给 javascript 运行时。

它确实引入了一个无限循环,每次调用之间延迟 1 秒

window.setTimeout(() => this.start(), 1000);

几乎与

var _this = this; 
window.setTimeout(function(){ _this.start(); }, 1000);

它被称为箭头函数

也许你需要setInterval.这将创建一个无限循环,您可以使用clearInterval清除该循环。

this.interval = window.setInterval(() => {
...
}, 5000);
window.clearInterval(this.interval);

你也可以做

this.sensors.forEach(sensor => sensor.check())

而不是使用for循环。

你不能在 setTimeout 中使用它,因为它指的是 setTimeout,而不是你的类。试试这个:

class MasterControlPanel {
    private sensors: Sensor[] = [];
    constructor() {
        // Instantiating the delegate HeatSensor
        this.sensors.push(new HeatSensor(this));
    }
    var that = this;
    start() {
        for (var i= 0; i < this.sensors.length; i++) {
            // Calling the delegate
            this.sensors[i].check();
        }
        window.setTimeout(() => that.start(), 1000);
    }
    startAlarm(message: string) {
        console.log('Alarm! ' + message);
    }
}
var cp = new MasterControlPanel();
cp.start();