簡體   English   中英

如何在執行下一個 function 之前等待 function 一定延遲

[英]How to wait for a function for a certain delay before executing the next function

假設我有兩個 function 我需要運行

await func1()
await func2()

我想等待最多 1000 毫秒讓func1()完成。 如果在 1000ms 內沒有完成則調用func2() ,不需要取消對 func1() 的請求

但是如果func1()在不到 1000 毫秒內返回,比如說 500 毫秒,那么它會立即執行func2()

我想嘗試一些自定義睡眠 function 但不確定如何提前退出睡眠。

您可以使用Promise.race()來限制執行時間。 它接受多個承諾並返回一個承諾,該承諾將在 promise arguments 中的第一個解決后立即解決:

 const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); //mock functions taking time const func1 = () => sleep(100); // 0.100s const func2 = () => sleep(2000); // 2s const func3 = () => sleep(300); // 0.300s //make a function that will clamp the wait time const maxWait = ms => promise => Promise.race([sleep(ms), promise]); async function main() { const noMoreThan1Second = maxWait(1000); console.time("func1"); await noMoreThan1Second(func1()); console.timeEnd("func1"); console.time("func2"); await noMoreThan1Second(func2()); console.timeEnd("func2"); console.time("func3"); await noMoreThan1Second(func3()); console.timeEnd("func3"); } main();

請注意, Promise.race()不會取消較慢的承諾鏈接到的任務。 由於 Promise 不控制異步任務,它們只是一種通知機制。 因此,使用Promise.race()僅僅意味着忽略較慢承諾的結果。 他們所做的異步任務仍然會在后台繼續,並且仍然可以成功或失敗。 如果需要處理拒絕,那么Promise.race()不會有任何變化:

 const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); async function func() { console.log("func() started"); await sleep(2000); console.log("func() finished"); } async function main() { console.log("calling func()"); await Promise.race([sleep(1000), func()]); console.log("finished waiting for func()"); } main();


作為更高級的用法,如果 promise 未及時解決,則可能會返回默認值:

 //allow optional value to be delayed const sleep = (ms, value) => new Promise(resolve => setTimeout(resolve, ms, value)); const maxWait = (ms, value) => promise => Promise.race([sleep(ms, value), promise]); const func1 = () => sleep(100, "one"); const func2 = () => sleep(2000, "two"); async function main() { const noMoreThan1Second = maxWait(1000, "default"); console.log(await noMoreThan1Second(func1())); console.log(await noMoreThan1Second(func2())); } main();

或者,如果某些事情花費的時間太長,可能會出現錯誤:

 //allow optional value to be delayed const sleep = (ms, value) => new Promise(resolve => setTimeout(resolve, ms, value)); const delayedReject = (ms, value) => new Promise((_, reject) => setTimeout(reject, ms, value)); const maxWait = (ms, value) => promise => Promise.race([delayedReject(ms, value), promise]); const func1 = () => sleep(100, "one"); const func2 = () => sleep(2000, "two"); async function main() { const noMoreThan1Second = maxWait(1000, "timeout"); try { console.log(await noMoreThan1Second(func1())); console.log(await noMoreThan1Second(func2())); } catch(e) { console.log("problem encountered:", e) } } main();

作為一個小提示,重復使用sleep()delayedReject()的替代實現將是:

const delayedReject = (ms, value) =>
    sleep(ms)
        .then(() => Promise.reject(value));

或更短的 eta-reduced版本:

const delayedReject = (ms, value) =>
    sleep(ms, value)
        .then(Promise.reject);

您可以使用下面的 function 為 promise 留出特定的時間來完成。 基本上,它會定期輪詢 promise,直到它穩定下來或超時到期。

 function wait(promise, maxTime) { let start = Number(new Date) let result = ['', null] promise.then(r => result = ['ok', r]).catch(r => result = ['error', r]) return new Promise((resolve, reject) => { function poll() { if (result[0] === 'ok') return resolve(result[1]) if (result[0] === 'error') return reject(result[1]) let now = Number(new Date) if (now - start > maxTime) return reject('timeout') window.requestAnimationFrame(poll) } poll() }) } // EXAMPLE: wait( fetch('https://jsonplaceholder.typicode.com/posts/1'), 10 ).then(r => console.log('OK', String(r))).catch(r => console.log('ERROR', String(r))) wait( fetch('https://jsonplaceholder.typicode.com/posts/1'), 1000 ).then(r => console.log('OK', String(r))).catch(r => console.log('ERROR', String(r)))

您可以使用Promise.race function 來執行此操作。 這是一個例子

 const func1 = new Promise(resolve => { setTimeout(() => { console.log("func1"); resolve("func 1") }, 1200); }) const func2 = () => {console.log("func2")}; const promiseMaximumWait = (promise, time) => { const controlPromise = new Promise((resolve) => { setTimeout(() => resolve("controlPromise"), time) }); return Promise.race([controlPromise, promise]); } promiseMaximumWait(func1, 1000).then((val) => { console.log(val); func2(); })

來自 MDN 文檔

Promise.race() 方法返回一個 promise,一旦可迭代中的一個承諾履行或拒絕,就會履行或拒絕,其值或原因來自該 promise。

因此,我們創建了一個控件 promise,它是一個 settimeout,其持續時間可以由我們自己設置,並將作為我們必須繼續前進的最長時間。 如果 func1 在那個時候解析,那么我們繼續 func1 的結果並立即執行 func2。 如果最長時間已經過去,我們從 controlPromise 獲取結果並執行 func2。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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