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

时间:2016-09-02 20:52:06

标签: javascript typescript

我看到了以下代码:

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()将首先迭代sensor内的每个sensors,然后调用window.setTimeout,然后start再次调用1 { {1}}第二次延迟。

参考:清单3-3。 Pro TypeScript中的委派:应用程序级JavaScript开发

4 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

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

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

它被称为Arrow Function

答案 2 :(得分:-1)

也许你需要update trace_tercile t set tercile = case when rank < 13 then 3 when rank < 25 then 2 else 1 end from ( select year, rank() over (order by value desc) from trace_tercile ) s where s.year = t.year; 。 那个会创建一个无限循环,您可以使用setInterval清除它。

clearInterval

你也可以

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

window.clearInterval(this.interval);

而不是使用this.sensors.forEach(sensor => sensor.check()) 循环。

答案 3 :(得分:-1)

你不能在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();