如果解决时间超过 5 秒,是否可以拒绝 Promise.allSettled 中的每个 Promise?
Is it possible to reject each Promise in Promise.allSettled if it takes more than 5 seconds to resolve?
我有一个 Promise.allSettled 用来解析数据库中的数据。我有一个 Promise 数组,我 运行 到 Promise.allSettled,然后我只使用已解决的 Promise。是否可以在 Promise.allSettled 内设置超时,以便如果 promise 在 5 秒后仍未解析数据,它应该 return 被拒绝?
我的代码如下所示:
await Promise.allSettled(promises)
.then(result => result.forEach(d => {
if (d.status === 'fulfilled') {
data.push(d.value)
}
}));
您可以在原始承诺和拒绝的超时承诺上使用 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));
使用自定义 Promise class 很简单 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}`);
});
我有一个 Promise.allSettled 用来解析数据库中的数据。我有一个 Promise 数组,我 运行 到 Promise.allSettled,然后我只使用已解决的 Promise。是否可以在 Promise.allSettled 内设置超时,以便如果 promise 在 5 秒后仍未解析数据,它应该 return 被拒绝?
我的代码如下所示:
await Promise.allSettled(promises)
.then(result => result.forEach(d => {
if (d.status === 'fulfilled') {
data.push(d.value)
}
}));
您可以在原始承诺和拒绝的超时承诺上使用 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));
使用自定义 Promise class 很简单 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}`);
});