簡體   English   中英

在某個時間 t 后或如果事件觸發(以先發生者為准)解決 promise

[英]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 resolvereject function,再次使用他們通常的名稱來reject所有功能) 因此,您所擁有的是編寫它的簡單方法。

如果您在事件處理程序或超時處理程序中執行具有諸如res(doSomethingAndReturnValue())之類的副作用的操作,將不是一個好主意,因為doSomethingAndReturnValue()部分仍會執行並具有其副作用。 但是在您的示例中,您沒有這樣做。


¹ 三個相當小的注釋:

  1. 我假設當你的事件處理程序被調用時,一些信息被傳遞給處理程序。 由於您直接使用res作為處理程序,因此它將接收該信息。 因此,您已將其設置為使用事件處理程序獲取的值(如果事件首先觸發)或undefined (如果計時器首先觸發)來滿足 promise,這意味着使用它的代碼會看到不同的實現值。

  2. 通常,我希望超時是拒絕而不是履行,但這取決於您的用例。

  3. 您的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM