使用箭头函数进行递归的SetTimeout

3

我想知道是否有办法使用箭头函数实现递归的setTimeout,并且可以在其中使用 this(例如,引用我的类属性)。实际上,当我使用普通函数声明我的setTimeout时,this = undefined

我得到:

public currentIndex: number = 0;

setTimeout(function run(){
    this.currentIndex++;
    console.log(this.currentIndex); // returns undefined
    setTimeout(run, 1000);
}, 1000)

改为:

setTimeout(() => {
    this.currentIndex++;
    console.log(this.currentIndex) // returns currentIndex value
    setTimeout( ?? , 1000) // What should i put instead of '??' ?
}, 1000)

你是否正在寻找使用setInterval来执行递归任务?https://developer.mozilla.org/en-US/docs/Web/API/setInterval - Himanshu Aggarwal
正如我回答ciekals11的那样,由于我的代码执行时间,setInterval似乎不适用于我的情况。 - Fab83i
另一种方法可能是使用await在迭代之间暂停的循环,例如for(;;await delay(1000)){ this.currentIndex++; } - Thomas
4个回答

1
您可以先绑定this,然后将此函数用于所有调用。
function run(reference) {
    this.currentIndex++;
    console.log(this.currentIndex); // returns undefined
    setTimeout(reference, 1000, reference);
}

const runThis = run.bind(thisReference);

setTimeout(runThis, 1000, runThis);

1

箭头函数不会在函数体内创建新的上下文,而普通函数会。因此,箭头函数中的this指向父级作用域,而普通函数中的this指向自身上下文。


1
这将会递归创建setTimeout。

let currentIndex = 0;

const run = () => {
    setTimeout(() => {
        currentIndex++;
        console.log(currentIndex);
        run();
    }, 1000);
}

run();

但更好的方法可能是(我不知道您的用例,所以只是可能)使用setInterval()

let currentIndex = 0;

const interval = setInterval(() => {
    currentIndex++;
    console.log(currentIndex);

    // stop interval
    if (currentIndex >= 10) {
        clearInterval(interval);
    }
}, 1000);


我本来会用setInterval但是我发现所选择的时间间隔并不能保证,因为程序的执行时间会影响。例如,如果代码执行时间超出预期,时间间隔就会受到影响。这是真的吗? - Fab83i
我认为这个回答了你的问题。 - ciekals11

0

可能最简单的方法是将箭头函数提取到自己的变量中:

const run = () => {
    this.currentIndex++;
    console.log(this.currentIndex);
    setTimeout(run, 1000);
};
setTimeout(run, 1000);

虽然在这个特定的例子中,您可以使用 setInterval 而不是 setTimeout 来进一步简化它,从而完全避免第二个 setTimeout 调用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接