如何在node.js + express中捕获“响应结束”事件?

我想编写一个快速中间件函数,在响应的“结束”事件(如果存在)上设置侦听器。 目的是根据最终处理程序决定发送的http响应代码进行清理,例如logging响应代码和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); } }); } 

当我尝试这个时,“结束”事件处理程序永远不会被调用。 res.on('close') ,我在另一篇文章中读到过。 这样的事件是否被解雇?

我能想到的唯一方法就是将res.endres.send与我自己的版本一起封装在一个自定义的中间件中。 这是不理想的,因为res.endres.send不需要callback,所以我不能把它们包装起来,调用原来的,然后根据响应代码来做我的事情,因为他们不会叫我回来)。

有一个简单的方法来做到这一点?

阅读文档 ,这里是res.send的签名:

 res.send(body|status[, headers|status[, status]]) 

这意味着你可以设置你自己的状态,像这样: res.send( 'some string', 200 ); 甚至只是res.send( 404 );

这个方法是你用来发送响应的方法。

一旦它被发送到客户端,你不能再访问它,所以没有callback。

这是你的服务器做的最后一件事。 一旦它处理了请求,它就发送响应。

但是,您可以将其发送给客户端之前访问它。 这意味着你可以:

 console.log( res ); res.send( datas ); 

如果你想回滚/提交,当你调用数据库的callback函数的时候,而不是在响应消失的时候。

奇怪的是,当响应closures时,响应似乎发出“完成”事件: http : //sambro.is-super-awesome.com/2011/06/27/listening-for-end-of-response-与-nodeexpress-JS /

尽pipe这个博客条目有点旧了 ,但这个事件仍然存在( lib / http.js中的第836行 ),所以我认为它不会很快消失,即使这两个节点都没有明确提及它。 到2014年初,它已经移动到lib / _http_outgoing.js的504行,并仍然有效。

顺便说一句,服务器响应的“错误”事件可能不是你通常想看到的。

为了进一步@ Amatsuyu的回应,这是它应该看起来如何:

 res.on('finish', function() { // do stuff here });