如果解决时间超过 5 秒,是不是可以拒绝 Promise.allSettled 中的每个 Promise?
Posted
技术标签:
【中文标题】如果解决时间超过 5 秒,是不是可以拒绝 Promise.allSettled 中的每个 Promise?【英文标题】:Is it possible to reject each Promise in Promise.allSettled if it takes more than 5 seconds to resolve?如果解决时间超过 5 秒,是否可以拒绝 Promise.allSettled 中的每个 Promise? 【发布时间】:2021-03-15 08:14:44 【问题描述】:我有一个 Promise.allSettled 用于解析数据库中的数据。我有一组通过 Promise.allSettled 运行的 Promise,然后我只使用已解决的 Promise。是否可以在 Promise.allSettled 中设置超时,这样如果一个 Promise 在 5 秒后仍未解决数据,它应该返回为被拒绝?
我的代码如下所示:
await Promise.allSettled(promises)
.then(result => result.forEach(d =>
if (d.status === 'fulfilled')
data.push(d.value)
));
【问题讨论】:
【参考方案1】:您可以在原始承诺和拒绝的超时承诺上使用Promise.race
,例如:
await Promise.allSettled(
promises.map(promise => Promise.race([promise, rejectAfterDelay(5000)])) // **
)
.then(result => result.forEach(d =>
if (d.status === 'fulfilled')
data.push(d.value)
));
...rejectAfterDelay
类似于:
const rejectAfterDelay = ms => new Promise((_, reject) =>
setTimeout(reject, ms, new Error("timeout"));
;
旁注:您可以使用filter
过滤掉被拒绝的承诺:
data.push(...
await Promise.allSettled(
promises.map(promise => Promise.race([promise, rejectAfterDelay(5000)]))
).then(result => result.filter((status) => status === "fulfilled"))
);
...虽然我认为我会将“allSettled
在超时内”部分重构为实用函数,例如:
const fulfilledWithinTimeout = async (promises, timeout) =>
promises = Array.isArray(promises) ? promises : [...promises];
const all = await Promise.allSettled(promises.map(promise => Promise.race([promise, rejectAfterDelay(timeout)]));
return all.filter((status) => status === "fulfilled");
;
然后
data.push(...await fulfilledWithinTimeout(promises, 5000));
【讨论】:
最后一个与旁注相关的问题。我可以过滤结果然后仅获取值列表吗?因此,您的代码过滤列表,因此列表中仅保留“已完成”。现在我还想要一个仅包含已完成值对象的列表。 :) 谢谢你 @Benji - 您通常会在filter
之后使用 map
:result => result.filter((status) => status === "fulfilled").map((value) => value)
【参考方案2】:
使用自定义 Promise 类很容易Demo:
import CPromise from "c-promise2";
CPromise.allSettled([...promises])
.timeout(1000)
.catch((err) =>
console.warn(`Fail: $err`); // Fail: CanceledError: timeout
);
这样的承诺可以处理取消:
import CPromise from "c-promise2";
CPromise.allSettled([
new CPromise((resolve, reject, onCancel ) =>
const timer = setTimeout(resolve, 2000);
onCancel(() =>
clearTimeout(timer);
console.log("Wow! timeout cleared");
);
)
])
.timeout(1000)
.catch((err) =>
console.warn(`Fail: $err`);
);
【讨论】:
以上是关于如果解决时间超过 5 秒,是不是可以拒绝 Promise.allSettled 中的每个 Promise?的主要内容,如果未能解决你的问题,请参考以下文章
怎样提高开机速度?怎样提高主板启动速度?如果提升超过5秒,重磅悬赏!!电脑配置见 问题补充 。
缓慢的Http拒绝服务攻击漏洞的验证(slowhttptest的安装)
确定 95% 的请求所用时间不超过 1 秒,如果超过则自动停止测试