使用 next() 的执行流程

Execution flow using next()

我是新手,对 next() 函数的机制有疑问。

  1. 我是否正确,一旦 next() 被调用,它会立即触发 app.get 的执行,而 next() 下面的所有内容都将异步执行?
  2. 如果是这样,为什么当我在 setTimeout() 中设置大延迟后 'Am I executed?' 没有打印到控制台?

请在下面的代码中解释执行流程。

app.param('seriesId', (req, res, next) => {
  ... // Check for presence of series
  console.log('I am executed');
  next();
  setTimeout(() => {console.log('Am I executed?')}, 1000); // Prints for 100, does not print for 1000
});

app.get('/:seriesId', (req, res, next) => {
  ... // Call to db to get series object
  res.status(200).json({series: series});
});

调用 next() 会将控制权交给管道中的下一个中间件。在您的示例中,这将是 app.get.

但是,该方法的行为不像 return 语句,因此您放置在后面的任何代码也会被执行。

给出下面的示例,如果您启动服务器并导航到 http://localhost:1337/foo,日志语句将是:

  1. 我们到了
  2. 正在执行获取
const express = require('express');

const app = express();

app.param('param',(req, res, next) => {
    next();
    setTimeout(() => console.log('well here we are'), 1000);
});

app.get('/:param', (req, res) => {
    setTimeout(() => {
        console.log('executing the get');
        res.status(200).send();
    }, 2000);
});

app.listen(1337);
console.log('app started at http://localhost:1337');

中间件中的分支

避免混淆的一个好习惯是确保对 next() 的调用放在执行的末尾。例如,不要这样做:

if(aCondition) {
    next()
}
next(new Error('Condition was false'));

但是:

if(aCondition) {
    next()
} else {
    next(new Error('Condition was false'));
}

或者,我所做的总是 return next() 调用,以避免中间件执行任何进一步的代码。

在中间件中执行异步代码

最后一点:如果你需要在你的中间件中执行异步代码,那么只有在这段代码执行完毕后才调用 next()

不要做:

loadUserFromDB()
    .then(u => req.user = u);
next();

但是:

loadUserFromDB()
    .then(u => {
         req.user = u;
         next();
    });