简体   繁体   English

如何在执行下一个 function 之前等待 function 一定延迟

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

Lets say i have two function i need to run假设我有两个 function 我需要运行

await func1()
await func2()

I want to wait for a maximum of 1000ms for func1() to complete.我想等待最多 1000 毫秒让func1()完成。 If it does not complete within the 1000ms then call func2() , don't need to cancel the request for func1()如果在 1000ms 内没有完成则调用func2() ,不需要取消对 func1() 的请求

But if the func1() returns in less than 1000ms, let's say 500ms, then it immediately executes the func2()但是如果func1()在不到 1000 毫秒内返回,比如说 500 毫秒,那么它会立即执行func2()

I thought of trying some custom sleep function but not sure on how I would exit the sleep before hand.我想尝试一些自定义睡眠 function 但不确定如何提前退出睡眠。

You can use Promise.race() to clamp the execution time.您可以使用Promise.race()来限制执行时间。 It accepts multiple promises and returns a single one that will resolve as soon as the first of the promise arguments resolves:它接受多个承诺并返回一个承诺,该承诺将在 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();

Note that Promise.race() will not cancel the task that the slower promise(s) are linked to.请注意, Promise.race()不会取消较慢的承诺链接到的任务。 Since promises do not control asynchronous tasks, they are simply a notification mechanism.由于 Promise 不控制异步任务,它们只是一种通知机制。 Therefore, using Promise.race() simply means ignoring the results of the slower promises.因此,使用Promise.race()仅仅意味着忽略较慢承诺的结果。 The async task they do would still continue in the background and can still succeed or fail.他们所做的异步任务仍然会在后台继续,并且仍然可以成功或失败。 If rejections need to be handled, then nothing changes with 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();


As a more advanced usage, default values might be returned if a promise is not resolved in time:作为更高级的用法,如果 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();

Alternatively, there could be an error if something takes too long:或者,如果某些事情花费的时间太长,可能会出现错误:

 //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();

As a small note, an alternative implementation of delayedReject() that re-uses sleep() would be:作为一个小提示,重复使用sleep()delayedReject()的替代实现将是:

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

or shorter eta-reduced version:或更短的 eta-reduced版本:

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

You can allow a specific time for a promise to complete using the function below.您可以使用下面的 function 为 promise 留出特定的时间来完成。 Basically, it polls the promise periodically until it either settles or the timeout expires.基本上,它会定期轮询 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)))

You can use Promise.race function for doing this.您可以使用Promise.race function 来执行此操作。 Here is an example这是一个例子

 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(); })

From MDN Docs来自 MDN 文档

The Promise.race() method returns a promise that fulfills or rejects as soon as one of the promises in an iterable fulfills or rejects, with the value or reason from that promise. Promise.race() 方法返回一个 promise,一旦可迭代中的一个承诺履行或拒绝,就会履行或拒绝,其值或原因来自该 promise。

So we have created a control promise which is a settimeout whose duration can be set by ourself and will act as the maximum time after which we have to move ahead.因此,我们创建了一个控件 promise,它是一个 settimeout,其持续时间可以由我们自己设置,并将作为我们必须继续前进的最长时间。 If the func1 resolves in that time, then we proceed with result from func1 and execute func2 immediately.如果 func1 在那个时候解析,那么我们继续 func1 的结果并立即执行 func2。 If the maximum time has elapsed we take the result from controlPromise and execute func2.如果最长时间已经过去,我们从 controlPromise 获取结果并执行 func2。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM