停止等待setTimeOut函数

时间:2020-01-04 03:01:42

标签: javascript typescript settimeout

我有一个称为delay()的Typescript函数,该函数在异步/等待模式下调用。

play(){
   (async () => { 
       await this.delay(90000);
       this.player.play();
   })();
}

delay(ms: number) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

有没有办法在完成90秒之前“杀死/中断” setTimeout,并在再次调用“播放”功能时再次开始计数?

6 个答案:

答案 0 :(得分:4)

您可能想要类似的东西

const delay = (ms: number) => {
    let id;

    const promise = new Promise(resolve => {
        id = setTimeout(resolve, ms);
    });

    return {
        id, promise
    };
}

const play = () => {
    const { id, promise } = delay(1000);
    promise.then(() => console.log("Promise called"));
    // Or call this to cancel
    clearTimeout(id);
};

但是我可以用另一种方式实现这一点:

const Timer = (ms: number) => {
    let id: number;

    const start = () => new Promise(resolve => {
        if (id === -1) {
            throw new Error('Timer already aborted');
        }

        id = setTimeout(resolve, ms);
    });

    const abort = () => {
        if (id !== -1 || id === undefined) {
            clearTimeout(id);
            id = -1;
        }
    }

    return {
        start, abort
    }
};

const timer = Timer(1000);
timer.start().then(() => console.log("done after 1000ms"));
timer.abort(); // this would abort the operation

// Calling timer.abort() before timer.start() would throw an error as well.

答案 1 :(得分:0)

setTimeout返回一个值。将值保存在某个地方,然后在要“杀死/中断”它时,在其上调用clearTimeout

答案 2 :(得分:0)

由于您的cancel函数返回了Promise,而ES6不允许您取消Promise。 Promise返回成功值或失败值。

要取消承诺,请使用

RxJS可观察对象或诸如蓝鸟之类的第三方库

答案 3 :(得分:0)

检查是否有帮助。 我们的想法是创建一个settimeout参考变量,使用它可以执行clearTimeout来停止以前的settimeout执行。

play = (()=>{let timeoutRef; return((number)=>{if(timeoutRef){clearTimeout(timeoutRef)};timeoutRef = setTimeout(()=>console.log("hello",number),number)})})()

注意代码格式,我使用jsconsole键入代码。:)

答案 4 :(得分:0)

看看“去抖动”功能。

import { debounce } from “lodash”;

class Player {
    constructor() {
        this.delayedPlay = debounce(this.play.bind(this), 9000);
    }
    play() {
        /* do stuff here */
    }
}

如果在第一次通话之前不到90秒内再次拨打debouncePlay,则第一次通话将被取消,并且新的计时器将开始计时。

Here is a more detailed explanation of the debounce function.

答案 5 :(得分:0)

您可以阅读here有关取消承诺的信息。

我创建了一个类,可以解决您的问题
我的课使用的是bluebird

的优势
class Delayer {
  constructor() {
    this.Promise = require('bluebird');
    this.Promise.config({
      cancellation: true
    })
    this.promise = null;
  }

  delay(ms) {
    if(this.promise) {
      this.promise.cancel();
    }
    this.promise = new this.Promise(resolve => setTimeout(resolve, ms));
    return this.promise;
  }
}

您的代码使用情况

// you need to run `npm install bluebird --save`

 const delayer = new Delayer(); // create a new instance of delayer to work with
   play(){
    (async () => { 
        await delayer.delay(90000);
        this.player.play();
    })();
 }
相关问题