json-server中间件执行顺序为何与Express存在差异?
为何Json-server中
foo会在after之后输出? 现象对比
Express环境下的执行结果
代码示例:
const express = require('express') const app = express() const router = createRouter(); app.use((req,res,next)=>{ console.log("before"); next(); console.log("after"); }) function createRouter() { const router = express.Router() router.render = (req,res)=>{ console.log("foo"); res.send("hello, foo") } router.use((req, res) => { router.render(req, res); }) return router; } app.use(router) app.listen(3000)
访问http://localhost:3000/时输出:
before foo after
Json-server环境下的执行结果
代码示例:
// server.js const jsonServer = require('json-server'); const app = jsonServer.create(); const router = jsonServer.router('db.json'); const middlewares = jsonServer.defaults(); app.use((req,res,next)=>{ console.log("before") next() console.log("after") }) router.render = (req, res) => { console.log("foo") res.send("hello, foo") } // Use router app.use(router) // Start server app.listen(3000)
访问后输出:
before after foo
原因解析
核心差异在于Json-server路由内部的异步处理逻辑:
- 在Express示例中,自定义的Router中间件是同步执行:调用
next()后,会立刻进入Router的中间件,同步执行router.render输出foo,等Router的所有同步逻辑走完,才回到外层中间件执行console.log("after")。 - 而Json-server的
jsonServer.router()创建的路由,内部会先执行一系列异步操作(比如读取db.json文件、解析数据等),哪怕你重写了render方法,next()调用后,Json-server并不会立刻执行你的render,而是把后续逻辑(包括你的render)放进Node.js的异步事件队列。此时外层中间件的next()之后的代码(after)会先执行,等异步任务完成后,才会触发你重写的router.render,输出foo。
内容的提问来源于stack exchange,提问作者Hu Jinhong
相关产品推荐
相关产品推荐

