gpt4 book ai didi

javascript - 如何在执行下一个函数之前等待一个函数一定的延迟

转载 作者:行者123 更新时间:2023-12-03 08:02:08 25 4
gpt4 key购买 nike

假设我有两个需要运行的函数

await func1()
await func2()

我想等待最多 1000 毫秒让 func1() 完成。如果在 1000 毫秒内没有完成,则调用 func2(),不需要取消对 func1() 的请求

但是,如果 func1() 在不到 1000 毫秒(假设是 500 毫秒)内返回,那么它会立即执行 func2()

我想尝试一些自定义 sleep 功能,但不确定如何提前退出 sleep 。

最佳答案

您可以使用Promise.race()来限制执行时间。它接受多个 Promise 并返回一个 Promise,该 Promise 将在第一个 Promise 参数解析后立即解析:

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 不控制异步任务,因此它们只是一种通知机制。因此,使用 Promise.race() 仅仅意味着忽略较慢的 Promise 的结果。他们执行的异步任务仍将在后台继续,并且仍然可能成功或失败。如果需要处理拒绝,则 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);

关于javascript - 如何在执行下一个函数之前等待一个函数一定的延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73800420/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com