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

Jak*_*ake 34 events response node.js express

我想编写一个快速中间件函数,在响应的'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();
}
Run Code Online (Sandbox Code Playgroud)

路线:

app.post ("/something", function (req, res) { 
    db.doSomething (function () {
       if (some problem) {
          res.send (500);
       } else {
          res.send (200);
       }
    });
 }
Run Code Online (Sandbox Code Playgroud)

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

我能想到的另一种方法是在自定义中间件中包装res.endres.send使用我自己的版本.这不是理想的,因为res.end并且res.send不接受回调,所以我不能只是包装它们,调用原始然后根据他们回电话时设置的响应代码做我的事情(因为他们不会打电话我回来了).

有一个简单的方法吗?

小智 42

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

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

顺便说一句,服务器响应上的"错误"事件可能不是您通常想要看到的.

  • 这是记录在案的"完成"事件吗?:http://nodejs.org/api/http.html#http_event_finish (6认同)
  • Express.js响应扩展了内置的http响应,而finish事件不是特定于Express的,因此它不在express expresss中 (5认同)

dmo*_*mon 29

为了进一步了解@Amatsuyu的回复,以下是它的外观:

res.on('finish', function() {
  // do stuff here
});
Run Code Online (Sandbox Code Playgroud)

  • 是的@MatthewHerbst。由于此事件侦听器是在 app.use 调用内处理的,因此只需从那里使用相同的“res”对象即可。 (2认同)

Flo*_*ine 0

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

res.send(body|status[, headers|status[, status]])
Run Code Online (Sandbox Code Playgroud)

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

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

一旦发送到客户端,就无法再访问它,因此没有回调。

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

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

console.log( res );
res.send( datas );
Run Code Online (Sandbox Code Playgroud)

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

  • res.on ('header',func) FTW! (4认同)