Node.js Express中middleware function的next参数相关疑问解答
next()的常见问题解答 我正在使用Node.js及Express.js进行开发,目前在处理middleware function,现有代码如下:
const express = require('express') const app = express() const myLogger = function (req, res, next) { console.log('LOGGED') next() } app.use(myLogger) app.get('/', (req, res) => { res.send('Hello World!') })
我对next参数存在疑惑,有以下关于middleware function的问题:
1. next的作用是什么?它是否会跳转到下一个middleware function?如果是,如何实现?
next()的核心作用就是把请求的控制权移交给Express中间件链里的下一个处理函数——这个函数可以是另一个自定义中间件,也可以是路由处理函数。
Express会严格按照你注册中间件/路由的顺序(比如app.use()的调用顺序、路由定义的先后)维护一条处理链。当你在中间件里调用next()时,Express就会找到链里的下一个函数并执行它。比如你代码里的myLogger执行完打印逻辑后调用next(),请求就会流转到后面的app.get('/')路由处理函数,最终返回"Hello World!"。
2. 若不存在第二个middleware function,会发生什么?
如果中间件链走到最后已经没有下一个处理函数了,Express会触发内置的默认处理逻辑:
- 如果请求还没有被任何路由或中间件发送响应,Express会自动返回404 Not Found响应,告诉客户端请求的资源不存在;
- 要是中间件链里出现了未捕获的错误,才会返回500错误。
举个例子,如果你删掉代码里的app.get('/'),访问根路径时myLogger调用next()后没有后续处理函数,客户端就会收到404响应。
3. 若不使用next,会发生什么?
如果在中间件里不调用next(),请求就会卡在当前中间件,永远无法到达后续的处理函数。客户端会一直处于等待响应的状态,直到超时断开连接。
比如你把代码里的next()删掉,访问根路径时控制台会打印"LOGGED",但客户端会一直转圈,永远收不到"Hello World!"——因为请求的控制权没交出去,路由处理函数根本没机会执行。
4. 能否在next中跳转到自定义middleware?
不能直接把自定义中间件函数传给next(),但可以通过以下方式间接实现类似效果:
- 用
next('route')跳过当前路由的后续中间件:如果你的自定义中间件是和某个路由绑定的,调用next('route')可以跳过当前路由里的其他中间件,直接转到下一个匹配的路由(如果这个路由挂载了你要的自定义中间件,就能触发它); - 错误处理中间件触发:如果你的自定义中间件是错误处理类型(参数为
err, req, res, next),可以调用next(err)直接触发它,Express会自动跳过正常的中间件链,执行错误处理中间件; - 提前注册中间件到指定路径:把目标自定义中间件用
app.use('/xxx', myCustomMiddleware)挂载到特定路径,然后在其他中间件里通过res.redirect('/xxx')或者让请求流转到该路径来触发它。
内容的提问来源于stack exchange,提问作者Brandy

