Koa - 异步函数错误处理中的异步函数

Koa - Async function within Async function error handling

在我的 app.js 中,我有以下...

app.use(async (ctx, next) => {
  try {
    await next()
  } catch (err) {
    ctx.status = 400
    ctx.body = `Uh-oh: ${err.message}`
    console.log('Error handler:', err.message)
  }
});

app.use(router());

然后在routes我定义了...

router.post('/', retrieve);

检索逻辑的结构如下...

const retrieve = async ctx => {
  Object.keys(ctx.request.files).forEach((key) => {
    process(files[key]);
  });
};

现在假设我在 retrieve...

中抛出一个错误
const retrieve = async ctx => {
  throw new Error(`Error!`);
  Object.keys(ctx.request.files).forEach((key) => {
    process(files[key]);
  });
};

这将正常工作并一直冒泡到 app.js。但是,process 函数也在使用 async,如果我在那里抛出错误...

const retrieve = async ctx => {
  Object.keys(ctx.request.files).forEach((key) => {
    process(files[key]);
  });
};

const process = async (file) => {
  throw new Error(`Error!`);
  ...

我收到以下错误...

UnhandledPromiseRejectionWarning: Error: Error!

为什么我得到 UnhandledPromiseRejectionWarning?我该如何修复它并使 process 内抛出的任何错误都冒泡到 app.js?

由于 forEach 循环不是异步的,错误会在它执行后抛出,因此无法冒泡到 app.js。现在有两种解决方案,您可以使用 for 循环,或者映射承诺并等待所有承诺解决。根据您的问题的示例代码:

  1. 顺序调用process
const retrieve = async ctx => {
    const ctxKeys = Object.keys(ctx.request.files);
    for(let i = 0 ; i < ctxKeys.length ;++i){
        await process(files[ctxKeys[i]]);
    }
};

  1. 异步调用process
const retrieve = async ctx => {
   await Promise.all(Object.keys(ctx.request.files).map(async (key) => {
     await process(files[key]);
   }));
};