[英]stop await setTimeOut function
我有一個名為 delay() 的 Typescript 函數,它在異步/等待模式下調用。
play(){
(async () => {
await this.delay(90000);
this.player.play();
})();
}
delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
有沒有辦法在完成 90 秒之前“殺死/中斷”setTimeout 並在再次調用“播放”函數時再次開始計數?
你可能想要類似的東西
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.
setTimeout
返回一個值。 將值保存在某處,然后當您想“殺死/中斷”它時,對其調用clearTimeout
。
由於您的取消函數返回一個承諾,而 ES6 不允許您取消承諾。 Promise 返回成功或失敗的值。
要實現取消承諾,請使用
RxJS observables 或第三方庫,如 bluebird
檢查這是否有幫助。 想法是我們創建一個 settimeout 參考變量,我們可以使用它來執行 clearTimeout,以停止先前的 settimeout 執行。
play = (()=>{let timeoutRef; return((number)=>{if(timeoutRef){clearTimeout(timeoutRef)};timeoutRef = setTimeout(()=>console.log("hello",number),number)})})()
注意代碼格式,我使用 jsconsole 輸入我的代碼。:)
看看“去抖動”功能。
import { debounce } from “lodash”;
class Player {
constructor() {
this.delayedPlay = debounce(this.play.bind(this), 9000);
}
play() {
/* do stuff here */
}
}
如果您在第一次調用前的 90 秒內再次調用debouncePlay
,則將取消第一次調用並啟動新的計時器。
您可以在此處閱讀有關 Promise 取消的信息。
我創建了一個可以幫助解決您的問題的類
我的班級正在使用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();
})();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.