使用 next() 的执行流程
Execution flow using next()
我是新手,对 next() 函数的机制有疑问。
- 我是否正确,一旦 next() 被调用,它会立即触发 app.get 的执行,而 next() 下面的所有内容都将异步执行?
- 如果是这样,为什么当我在 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,日志语句将是:
- 我们到了
- 正在执行获取
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();
});
我是新手,对 next() 函数的机制有疑问。
- 我是否正确,一旦 next() 被调用,它会立即触发 app.get 的执行,而 next() 下面的所有内容都将异步执行?
- 如果是这样,为什么当我在 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,日志语句将是:
- 我们到了
- 正在执行获取
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();
});