admin管理员组文章数量:1406919
I have a Typescript function called delay() that is invoked in async/await mode.
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 plete the 90 seconds and start the counting again when the "play" function is invoked again?
I have a Typescript function called delay() that is invoked in async/await mode.
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 plete the 90 seconds and start the counting again when the "play" function is invoked again?
Share Improve this question asked Jan 4, 2020 at 3:01 acgacg 5133 gold badges13 silver badges27 bronze badges 1-
use
clearTimeout()
– Marc Commented Jan 4, 2020 at 3:05
6 Answers
Reset to default 9You 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.
You can read here about Promise cancelation.
I have created a class that can be useful to solve your problem
My class is using the advantages of bluebird library
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();
})();
}
setTimeout
returns a value. Save the value somewhere, then when you want to "kill/interrupt" it, call clearTimeout
on it.
Since your cancel function returns a promise, and ES6 does not allow you to cancel a promise. Promise returns either success or failed value.
To achieve cancelation of promise either use
RxJS observables or third-party libraries like the 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.
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.:)
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.
Here is a more detailed explanation of the debounce function.
本文标签: javascriptstop await setTimeOut functionStack Overflow
版权声明:本文标题:javascript - stop await setTimeOut function - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744355987a2602306.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论