[英]Resolving a promise after some time t or if an event fires, whichever occurs first
我有一個名為wait
的 function,它接受以毫秒為單位的時間並返回 promise。 promise 如果myEvent
被觸發或經過一段時間ms
后應該得到解決,以先發生者為准。 目前我正在做這樣的事情,我認為這不是正確的方法。
async function wait(ms) {
return new Promise((res) => {
myEmitter.on('myEvent', res);
setTimeout(res, ms);
});
}
有一個更好的方法嗎?
你正在做的很好。¹一旦 promise 得到解決(通過第一次調用resolve
resolve
或reject
function,再次使用他們通常的名稱來reject
所有功能) 因此,您所擁有的是編寫它的簡單方法。
如果您在事件處理程序或超時處理程序中執行具有諸如res(doSomethingAndReturnValue())
之類的副作用的操作,那將不是一個好主意,因為doSomethingAndReturnValue()
部分仍會執行並具有其副作用。 但是在您的示例中,您沒有這樣做。
¹ 三個相當小的注釋:
我假設當你的事件處理程序被調用時,一些信息被傳遞給處理程序。 由於您直接使用res
作為處理程序,因此它將接收該信息。 因此,您已將其設置為使用事件處理程序獲取的值(如果事件首先觸發)或undefined
(如果計時器首先觸發)來滿足 promise,這意味着使用它的代碼會看到不同的實現值。
通常,我希望超時是拒絕而不是履行,但這取決於您的用例。
您的 function 不需要async
修飾符,因為它從不使用await
。 function 不需要async
,因為它返回 promise。 作為一年左右對規范的規范性更改,如果您像您正在做的那樣從async
function 返回本機 promise 不再有任何區別(它曾經非常短暫地延遲事情),但沒有理由它。
你的代碼是正確的。 promise 只能解決一次 - 如果您解決兩次,第二次實際上是空操作。
話雖如此,作為替代方案,您可以使用具有相同想法的Promise.race
。 它將 Promise 作為輸入,並將產生一個 promise,當第一個輸入的 Promise 完成時,該 promise 就會完成。
例如,單擊此處的按鈕會結算 promise,但它也會在 10 秒內結算:
let buttonResolve; let buttonPromise = new Promise(res => buttonResolve = res); document.querySelector("button").addEventListener("click", buttonResolve) let timedPromise = new Promise(res => setTimeout(res, 10000)); let start = Date.now(); Promise.race([buttonPromise, timedPromise]).then(() => console.log(`finished in ${(Date.now() - start) / 1000}s`))
<button>Click me</button>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.