- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我有两个需要运行的函数
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/
我正在尝试开发右边框/Angular 具有特定 Angular (30°) 的表格。我见过一些类似的解决方案,但它们都无法在一定程度上发挥作用。如果我想从 30° 改变到 20°,我不想花太多力气。
我是一名优秀的程序员,十分优秀!