[英]stop await setTimeOut function
I have a Typescript function called delay() that is invoked in async/await mode.我有一个名为 delay() 的 Typescript 函数,它在异步/等待模式下调用。
play(){
(async () => {
await this.delay(90000);
this.player.play();
})();
}
delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
Is there a way to "kill/interrupt" the setTimeout before complete the 90 seconds and start the counting again when the "play" function is invoked again?有没有办法在完成 90 秒之前“杀死/中断”setTimeout 并在再次调用“播放”函数时再次开始计数?
You probably want something like你可能想要类似的东西
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);
};
But I'd implement this in another way:但我会以另一种方式实现这一点:
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.
setTimeout
returns a value. setTimeout
返回一个值。 Save the value somewhere, then when you want to "kill/interrupt" it, call clearTimeout
on it.将值保存在某处,然后当您想“杀死/中断”它时,对其调用clearTimeout
。
Since your cancel function returns a promise, and ES6 does not allow you to cancel a promise.由于您的取消函数返回一个承诺,而 ES6 不允许您取消承诺。 Promise returns either success or failed value. Promise 返回成功或失败的值。
To achieve cancelation of promise either use要实现取消承诺,请使用
RxJS observables or third-party libraries like the bluebird RxJS observables 或第三方库,如 bluebird
check if this can help.检查这是否有帮助。 idea is we create a settimeout reference variable using which we can do clearTimeout, to stop previous settimeout execution.想法是我们创建一个 settimeout 参考变量,我们可以使用它来执行 clearTimeout,以停止先前的 settimeout 执行。
play = (()=>{let timeoutRef; return((number)=>{if(timeoutRef){clearTimeout(timeoutRef)};timeoutRef = setTimeout(()=>console.log("hello",number),number)})})()
mind the code formatting, I used jsconsole to type in my code.:)注意代码格式,我使用 jsconsole 输入我的代码。:)
Take a look at "debounced" function.看看“去抖动”功能。
import { debounce } from “lodash”;
class Player {
constructor() {
this.delayedPlay = debounce(this.play.bind(this), 9000);
}
play() {
/* do stuff here */
}
}
If you make a second call of debouncePlay
in less than 90 seconds before the first call, the first call will be canceled and a new timer will start.如果您在第一次调用前的 90 秒内再次调用debouncePlay
,则将取消第一次调用并启动新的计时器。
Here is a more detailed explanation of the debounce function. 以下是去抖动功能的更详细说明。
You can read here about Promise cancelation.您可以在此处阅读有关 Promise 取消的信息。
I have created a class that can be useful to solve your problem我创建了一个可以帮助解决您的问题的类
My class is using the advantages of bluebird library我的班级正在使用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;
}
}
Your code usage您的代码使用情况
// 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();
})();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.