【问题标题】:How to await on next() in a middleware如何在中间件中等待 next()
【发布时间】:2019-09-23 19:55:50
【问题描述】:

使用 express,我有一个这样的中间件:

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

如何等待这个 next() 完成 pls ? 我问的原因是我在 next() 之后添加了 console.log,此消息发生在下一个路由函数中的消息之前。

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

【问题讨论】:

  • Express 中没有next() 的接口来知道所有其他请求处理程序何时完成。 next() 本身基本上是异步的,因此当其他请求处理程序完成时,您无法判断它何时返回。 next() 只是启动路由器中的下一个链接,当它返回时,不一定与路由完成时有任何关系。所以,你的问题真的不能那样做。
  • 哦,next() 不返回承诺,因此您不能使用 await 来了解有关何时完成的任何信息。对于更以承诺为中心的设计,您可能需要查看KoaExpress v5 (in alpha)

标签: node.js express


【解决方案1】:

我在我的项目中遇到了这个问题,我们快速解决了将中间件一分为二的问题。您在路由之前添加第一部分,然后在“next()”之后添加要执行的内容,然后再添加。如果您需要访问相同的对象实例或其他内容,您始终可以将其保存在请求本地。

我的例子:


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}`);
});

这将是您遇到的问题。它会在这些行中打印一些东西。

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

-- 4

解决办法:

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}`);
});

您将中间件一分为二,以确保中间件 2 仅在路由中的所有内容都执行后才执行。你会得到如下输出:

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

【讨论】:

  • 我认为你是对的!没有其他解决方案,Expressjs 的耻辱!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-08
相关资源
最近更新 更多