Mao*_*ion 1 javascript node.js promise typescript es6-promise
TL;DR:我正在寻找一种策略或示例来处理未知数量的承诺拒绝,并X在用于多个异步调用时重试它们一段时间Promise.allSettled()。
读完这篇文章后:https://www.coreycleary.me/better-handling-of-rejections-using-promise-allsettled 我对这句话感到非常兴奋:
这很棒,因为我们仍然可以加载用户帐户信息,并稍后重试获取用户活动。(重试超出了本文的范围,并且有多种策略)
然而,在网上研究时,我发现完全没有具体的例子,甚至没有直接处理这个问题的帖子。
这是一些示例代码:
public async test() {
try {
console.log('trying..');
const multiAsync = [this.somethingA(), this.somethingB(), this.somethingC()];
const [a, b, c] = await Promise.allSettled(multiAsync);
} catch (e) {
console.log('catch');
console.log(e);
}
}
Run Code Online (Sandbox Code Playgroud)
现在假设对于上面的代码,A 和 C 都失败了,我想重试它们,比如说——再试一次。即使我有a, b, c,我也只知道哪些是fullfilled:true,哪些不是。但我不知道如何链接a回somethingA()和仅c重somethingC()试这两个函数,而且我绝对不想调用somethingB()两次。
有任何想法吗?
Promise 不会保留任何其来源的记录:一旦有了 Promise,就没有什么可以让您多次重试其来源。因此,常见的 Promise 重试模式接受 Promise 返回函数(“promise 工厂”),而不仅仅是 Promise 本身。在调用or之前将每个单独的 Promise 包装在重试函数中是最实用的解决方案allallSettled,因为快速失败的 Promise 可以立即重试,而无需像那样等待整个列表allSettled。
const multiAsync = [
retry(() => this.somethingA(), 3),
retry(() => this.somethingB(), 3),
retry(() => this.somethingC(), 3),
];
const [a, b, c] = await Promise.allSettled(multiAsync);
// or
const [a, b, c] =
await Promise.allSettled([/* functions */].map(x => retry(x, 3));
Run Code Online (Sandbox Code Playgroud)
但是,如果您想了解如何Promise.allSettled直接执行此操作,我这里有一个。我的解决方案不考虑超时,您可以通过Promise.race实现全局或单独添加超时。
/**
* Resolves a series of promise factories, retrying if needed.
*
* @param {number} maxTryCount How many retries to perform.
* @param {Array<() => Promise<any>>} promiseFactories Functions
* that return promises. These must be functions to enable retrying.
* @return Corresponding Promise.allSettled values.
*/
async function allSettledWithRetry(maxTryCount, promiseFactories) {
let results;
for (let retry = 0; retry < maxTryCount; retry++) {
let promiseArray;
if (results) {
// This is a retry; fold in results and new promises.
promiseArray = results.map(
(x, index) => x.status === "fulfilled"
? x.value
: promiseFactories[index]())
} else {
// This is the first run; use promiseFactories only.
promiseArray = promiseFactories.map(x => x());
}
results = await Promise.allSettled(promiseArray);
// Avoid unnecessary loops, though they'd be inexpensive.
if (results.every(x => x.status === "fulfilled")) {
return results;
}
}
return results;
}
/* test harness below */
function promiseFactory(label) {
const succeeds = Math.random() > 0.5;
console.log(`${label}: ${succeeds ? 'succeeds' : 'fails'}`);
return succeeds
? Promise.resolve(label)
: Promise.reject(new Error(`Error: ${label}`));
}
allSettledWithRetry(5, [
() => promiseFactory("a"),
() => promiseFactory("b"),
() => promiseFactory("c"),
() => promiseFactory("d"),
() => promiseFactory("e"),
]).then(console.log);Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2260 次 |
| 最近记录: |