40

我想编写一个快速中间件函数,它在响应的“结束”事件(如果存在)上设置一个侦听器。目的是根据最终处理程序决定发送的http响应代码进行清理,例如记录响应代码和数据库事务的回滚/提交。即,我希望此清理对最终调用者透明。

我想在 express 中执行以下操作:

路由中间件

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不接受回调,所以我不能只包装它们,调用原始代码,然后根据他们给我回电时设置的响应代码做我的事情(因为他们不会打电话我回来了)。

有没有一种简单的方法可以做到这一点?

4

3 回答 3

48

奇怪的是,当响应关闭时,响应似乎会发出“完成”事件: https ://web.archive.org/web/20120825112648/http://sambro.is-super-awesome.com/2011/ 06/27/listening-for-end-of-response-with-nodeexpress-js/

尽管这个博客条目有点旧,但这个事件仍然存在(lib/http.js 中的第 836 行),所以我认为它不会很快消失,即使节点和 express 的文档都没有提到它。到 2014 年初,它已移至lib/_http_outgoing.js 的第 504 行,并且仍然有效。

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

于 2012-08-07T08:21:19.447 回答
41

只是为了进一步@Amatsuyu的回应,它应该是这样的:

res.on('finish', function() {
  // do stuff here
});
于 2016-06-27T15:12:25.447 回答
0

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

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

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

此方法是您用来发送响应的方法。

一旦发送到客户端,就不能再访问了,所以没有回调。

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

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

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

如果要回滚/提交,请在调用数据库回调时执行,而不是在响应消失时执行。

于 2012-06-21T14:21:28.620 回答