Solvedkoa router router does not await async functions

Hi

I am using the following versions
nodejs v7.7.1
+-- koa@2.2.0
+-- koa-router@7.2.0

My problem is that the router returns without awaiting for the async function to resolve. The sample code is below:

router.get('/relay', async (ctx) => {
  const token = await relay();
  ctx.status = 200;
  ctx.body = token;
});

async function relay() {
  return await timeout(5000);
}

async function timeout(delay) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("random");
    }, delay);
  });
};

I can see from my logs that the route /relay returns immediately with a 404. The timeout function is called asynchronously and when it tries to set the ctx status the following error is thrown.
AssertionError: headers have already been sent

There does not seem to be a clear way to achieve what I want. I simply want to await an asynchronous function and return once it is resolved. How can I do this?

15 Answers

✔️Accepted Answer

I also encountered a similar problem. I got a 404 error as long as I called an asynchronous function in the route. But if I don't call any asynchronous function, there's no problem
The reason is that one of a middlewares does not use the await modifier when calling the next() method. ( Even if it doesn't seem to have anything to do with the router )
I guess this may cause the middleware to continue executing without waiting for the return result of the next middleware.
eg:

// this is wrong
app.use(function (ctx, next) {
    ctx.set("Access-Control-Allow-Origin", "*");
    next();
});
// this is right
app.use(async function (ctx, next) {
    ctx.set("Access-Control-Allow-Origin", "*");
    await next();
});

Other Answers:

@rosshadden you need to either await next(); or return next(); otherwise Koa has no idea that you're doing something async and your function won't wait on downstream middleware.

@crcrcry @ccsang The problem usually lies in the code that you must be calling. When using async await, you need to make sure that the entire call stack uses the same paradigm. If any of the functions in the stack do not await an async function, the desired result is not seen.

Check if you are using some external libraries that might be triggering functions asynchronously.