简体   繁体   中英

How to await on next() in a middleware

Using express, i have a middleware like this:

app.use((req, res, next) => {
  console.log(req);
  next();
});

How to wait on this next() to finish pls? The reason i'm asking is i added console.log after next(), this message is happening before the message in the next route function.

app.use(async(req, res, next) => {
  console.log(req);
  await next();
  console.log('should be the last print but ...');
});

I encountered this problem in my project and we went for a quick work around where we split the middleware in two. You add the first part before the routing and the things you want to execute after the "next()" in another one which you add afterwards. If you need to access the same object instances or something you can always save it in the request locals.

My example:


const express = require('express');
const app = express();
const port = 5050;
const wait = (milliseconds) =>
    new Promise((res, rej) => {
        setTimeout(() => {
            res();
        }, milliseconds);
    });

const middleware = async (req, res, next) => {
    console.log('- 1');
    await wait(10);
    console.log('- 2');
    next();
    console.log('- 3');
    await wait(10);
    console.log('- 4');
    console.log('');
};
app.use(middleware);
app.get('/', async (req, res, next) => {
    console.log('-- 1');
    await wait(10);
    console.log('-- 2');
    console.log('hello');
    res.send('Hello World!');
    console.log('-- 3');
    await wait(10);
    console.log('-- 4');
    next();
    return;
});

app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`);
});

This would have the issue you encountered. It would print something amongst those lines.

- 1
- 2
-- 1
- 3
-- 2
hello
-- 3
- 4

-- 4

The solution:

const express = require('express');
const app = express();
const port = 5050;
const wait = (milliseconds) =>
    new Promise((res, rej) => {
        setTimeout(() => {
            res();
        }, milliseconds);
    });

const middleware1 = async (req, res, next) => {
    console.log('- 1');
    await wait(10);
    console.log('- 2');
    next();
};

const middleware2 = async (req, res, next) => {
    console.log('- 3');
    await wait(10);
    console.log('- 4');
    console.log('');
    next();
};

app.use(middleware1);
app.get('/', async (req, res, next) => {
    console.log('-- 1');
    await wait(10);
    console.log('-- 2');
    console.log('hello');
    res.send('Hello World!');
    console.log('-- 3');
    await wait(10);
    console.log('-- 4');
    next();
    return;
});
app.use(middleware2);

app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`);
});

You split the middlewares in two so as to make sure that middleware2 is executed only after everything in the route is executed. You would get an output like:

- 1
- 2
-- 1
-- 2
hello
-- 3
-- 4
- 3
- 4

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM