我想编写一个快速中间件函数,在响应的'end'事件(如果存在)上设置一个监听器。目的是基于结束处理程序决定发送的http响应代码进行清理,例如,记录响应代码和db事务的回滚/提交。即,我希望这个清理对结束调用者是透明的。
我想在快递中做以下的事情:
路由中间件
function (req, res, next) {
res.on ('end', function () {
// log the response code and handle db
if (res.statusCode < 400) { db.commit() } else { db.rollback() }
});
next();
}
路线:
app.post ("/something", function (req, res) {
db.doSomething (function () {
if (some problem) {
res.send (500);
} else {
res.send (200);
}
});
}
当我尝试这个时,'end'事件处理程序永远不会被调用。 res.on('close')
也是如此,我在另一篇文章中读到了这一点。这样的事件会被解雇吗?
我能想到的唯一另一种方法就是在自定义中间件中使用我自己的版本包装res.end
或res.send
。这并不理想,因为res.end
和res.send
不接受回调,所以我不能只是将它们包起来,调用原始文件然后根据它们设置的响应代码来做我的事情给我回电话(因为他们不会给我回电话)。
有一种简单的方法吗?
答案 0 :(得分:42)
奇怪的是,当响应关闭时,响应会发出“完成”事件: http://sambro.is-super-awesome.com/2011/06/27/listening-for-end-of-response-with-nodeexpress-js/
尽管这篇博文有点陈旧,但这个事件仍然存在(Line 836 in lib/http.js),所以我认为它不会很快消失,即使节点也没有表达'文档提到它。 到2014年初,它已转移到line 504 on of lib/_http_outgoing.js并仍然有效。
顺便说一句,服务器响应中的“错误”事件可能不是您通常想要看到的内容。
答案 1 :(得分:27)
为了进一步了解@Amatsuyu的回复,以下是它的外观:
res.on('finish', function() {
// do stuff here
});
答案 2 :(得分:1)
阅读documentation,这是res.send
的签名:
res.send(body|status[, headers|status[, status]])
这意味着您可以设置自己的状态,例如:res.send( 'some string', 200 );
或甚至res.send( 404 );
。
此方法是您用来发送响应的方法。
一旦发送到客户端,您将无法再访问它,因此没有回调。
这是您服务器的最后一件事。处理完请求后,会发送响应。
但是,您可以在之前将其发送到客户端。这意味着你可以:
console.log( res );
res.send( datas );
如果要回滚/提交,则在调用数据库的回调时执行此操作,而不是在响应消失时执行。