【发布时间】:2022-11-16 08:25:17
【问题描述】:
我试图以受控方式强制拒绝 promise.allSettled() 函数。
这个想法是通过 API 批量运行一系列 url,这个 API 不时为给定请求返回 500 错误,并且可以安全地重试。所以我想在 promise.allSettled() 上触发拒绝,我可以在其中收集失败的 url,然后在递归时重新运行。
批量请求功能
export async function batchRequest(poolLimit, array, iteratorFn, exception) {
const promises = []
const racers = new Set()
for (const item of array) {
const pro = Promise.resolve().then(() => iteratorFn(item, array))
promises.push(pro)
racers.add(pro)
const clean = () => racers.delete(pro)
pro.then(clean).catch(clean)
if (racers.size >= poolLimit) await Promise.race(racers)
}
const results = await Promise.allSettled(promises)
// Collect errors rejected by iteratorFn,
const rejected = results
.filter(({ status, reason }) => status === 'rejected' && reason.name === exception)
.map(({ reason }) => reason.error)
// Recurse the array of rejected urls
if (rejected.length) {
await batchRequest(poolLimit, rejected, iteratorFn, exception)
}
}
在这里,我们正常运行承诺,但收集所有被拒绝的 url,我试图使用 exception 'timeout' 作为规则来确定它是否需要重新运行,因为它只是一个超时错误。
迭代函数
async function runRequest(url) {
try {
const { data } = await axios('https://exampleAPI.com')
// Take the data and write it somewhere...
} catch (error) {
if (error.response.status === 500) {
throw { name: 'timeout', url }
}
}
})
const urls = [...many urls]
await batchRequest(100, urls, runRequest, 'timeout')
我收到一条错误消息
This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "#<Object>".] { code: 'ERR_UNHANDLED_REJECTION' }
我如何强制对promise.allSettled() 进行受控拒绝?
更新------
我发现未处理的拒绝是在我开始 batchrequest 的时候
await batchRequest(100, urls, runRequest, 'timeout')
我需要在那里尝试捕获,但重点是使用 promise.allSettled() 来吸收错误而不是脱离 batchrequest
【问题讨论】:
-
“我收到一条错误消息,说我无法将其放入捕获物中“ 是什么确切的错误?因为you most definitely can throw in a catch
-
我得到这个
This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason并在它到达catch块时发生 -
这并不是说你不能把它扔进一个陷阱里。它只是说有一个未处理的承诺拒绝。所以,找到它是哪一个并处理它。
标签: javascript node.js async-await promise