发现了类似的问题,但没有一个回答我的问题。在抛出错误之前,我需要尝试运行3次异步函数。目前,它是通过while循环来完成的,这从一开始就不合适。这一切都是在明确的过程中发生的。这是我的代码当前的样子:
const MAX_NUMBER_OF_TRIES = 3
router.post('/', async function (req, res) {
let tries = 0
while (true) {
try {
await myAsyncFunction(body)
res.json({ success: true, message: 'Done!' })
} catch (err) {
if (tries >= MAX_NUMBER_OF_TRIES) {
res.json({ success: false, message: err && err.message })
}
}
tries++
}
}
问题之一是,当我这样做时,总是会出现以下错误:
UnhandledPromiseRejection警告:错误[ERR_HTTP_HEADERS_SENT]:将标头发送到客户端后无法设置标头
没有循环就不会出现。 所以我想问题是,如何在响应错误之前将这些调用限制为三个尝试?这是正确的路径还是还有另一种方法?为什么我的标题出现问题?
答案 0 :(得分:2)
您应该像这样在res.json({ success: false, message: err && err.message })
之后返回:
...
res.json({ success: false, message: err && err.message })
return
...
答案 1 :(得分:2)
是的,while
循环看起来很粗略。你永远不会停止。只需使用普通循环即可。另外,当您收到回复时,您需要休息一下。
const MAX_NUMBER_OF_TRIES = 3
router.post('/', async function (req, res) {
var message;
for (let tries = 0; tries < MAX_NUMBER_OF_TRIES; tries++) {
try {
await myAsyncFunction(body)
res.json({ success: true, message: 'Done!' })
return
// ^^^^^^
} catch (err) {
message = err && err.message;
console.log(`Try ${tries}: ${err}`)
}
}
res.json({ success: false, message })
}
这种奇怪的控制流程的另一种选择是使用递归,它非常适合重试:
async function getResult(body, retries) {
try {
await myAsyncFunction(body)
return {success: true, message: 'Done'}
} catch(err) {
if (retries > 0)
return getResult(body, retries-1)
else
return {success: false, message: err && err.message}
}
}
const MAX_NUMBER_OF_TRIES = 3
router.post('/', async function (req, res) {
const RETRIES = MAX_NUMBER_OF_TRIES - 1
res.json(await getResult(body, RETRIES))
})
答案 2 :(得分:1)
将重试逻辑移至异步功能,如下所示 这只是实现它的一个示例,可以根据需要进行调整。
router.post('/', async function(req, res) {
try {
var result = await asyncFunc(3 /* retries */);
res.send(result);
} catch(ex)
{
res.send(ex);
}
})
在异步功能中,您可以实现类似
async asyncFunc(retries)
{
for(var i = 0; i < retries; i++)
{
var result = await doSomething();
if(result)
{
// break the loop
return result;
}
}
// if we land here, so the number of retries was exceeded
throw Error("...");
}
答案 3 :(得分:0)
async-retry软件包将为您完成此任务;代码量实际上实际上是相似的,但是它具有更多的功能,并且不太正确。
例如:
const retry = require('async-retry')
try {
await retry(async () => {
await myAsyncFunction(body)
res.json({ success: true, message: 'Done!' })
}, {
retries: 3,
})
} catch (err) =>
{
res.json({ success: false, message: err && err.message })
}
外部捕获器处理重试三次并逃脱retry
块的情况。您还可以设置一个onError
函数,该函数具有针对每个错误(例如记录)执行的逻辑。