繁体   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