Node.js Express中Get请求返回响应后无法调用后续函数的问题
我来帮你拆解下为啥cache.setExp的日志没输出,一步步解决这个问题:
核心问题1:next() 从未被执行
看你的getPostsDataByQuery函数,最后一行是return res.json(rows);——这行代码会直接终止函数执行,后面的next()根本不会被调用。
在Express的中间件链里,只有当前中间件主动调用next(),框架才会把控制权传递给下一个中间件。你的路由配置是router.route('/posts').get(post.getPosts, post.setCache);,意味着setCache是getPosts之后的中间件,但因为getPosts里没触发next(),setCache函数压根没机会执行,自然cache.setExp的日志打不出来。
核心问题2:setCache 无法访问 rows 变量
就算next()被执行了,setCache里的rows是getPostsDataByQuery的局部变量,setCache根本访问不到这个值,调用cache.setExp(req, rows)会直接抛出rows is not defined的错误。
解决方案:调整中间件执行逻辑
步骤1:修改 getPostsDataByQuery,传递数据并触发 next()
把直接返回响应的逻辑改成将数据挂载到req对象上,然后调用next()让后续中间件执行:
function getPostsDataByQuery(queryString, req, res, next){ logger.info('start',req.route.path); // 此处省略部分代码(假设你已成功获取rows数据) // 将数据挂载到req对象,让后续中间件可以访问 req.postsData = rows; // 调用next(),把控制权传递给setCache next(); };
步骤2:修改 setCache,获取数据、设置缓存并返回响应
现在setCache可以从req拿到数据,处理缓存后再返回响应给客户端:
exports.setCache = function(req, res, next){ console.log('here in set function'); // 从req对象中获取之前查询到的posts数据 const rows = req.postsData; // 执行缓存设置逻辑 cache.setExp(req, rows); // 返回响应给客户端 res.json(rows); };
可选方案:先返回响应,再异步设置缓存
如果你希望优先给客户端返回响应,再后台处理缓存,可以利用Express的res.finish事件,这样不需要改变响应的发送时机:
修改getPostsDataByQuery:
function getPostsDataByQuery(queryString, req, res, next){ logger.info('start',req.route.path); // 此处省略部分代码 // 先给客户端返回响应 res.json(rows); // 监听响应完成事件,在响应发送后执行缓存逻辑 res.on('finish', () => { cache.setExp(req, rows); }); // 调用next()保持中间件链完整性(如果setCache还有其他逻辑的话) next(); };
这种情况下,setCache可以简化为仅处理其他逻辑,或者你甚至可以直接把缓存逻辑放在finish事件里,去掉setCache中间件。
修改完成后,cache.setExp的日志就能正常输出,同时也解决了rows变量的访问问题。
内容的提问来源于stack exchange,提问作者Mukesh S

