为什么我可以在“res.send”之后执行代码?

时间:2013-04-23 22:54:14

标签: node.js express

我想知道以下代码行为背后的机制是什么:

res.send(200, { data: 'test data' });
console.log('still here...');

我的理解是res.send返回该函数,但关闭连接/结束请求。这可以解释为什么我仍然可以在res.send命令后执行代码(我查看了快速源代码并且它似乎不是异步函数)。

还有什么东西在玩,我可能会失踪吗?

3 个答案:

答案 0 :(得分:95)

当然end结束了HTTP响应,但它对您的代码没有任何特殊之处。

即使您已经结束回复,也可以继续做其他事情。

无法做的事情对res执行任何有用的操作。由于响应结束,您无法向其写入更多数据。

res.send(...);
res.write('more stuff'); // throws an error since res is now closed

此行为与其他传统框架(PHP,ASP等)不同,后者将线程分配给HTTP请求并在响应结束时终止线程。如果调用ASP的Response.End之类的等效函数,则线程终止并且代码停止运行。在节点中,没有要停止的线程。 reqres不会再触发任何事件,但回调中的代码可以自由继续运行(只要它不会尝试调用需要res的{​​{1}}上的方法有效的回应是开放的。)

答案 1 :(得分:37)

编辑:我不再执行下面的说明,因为在不需要时不应返回值。它使您的代码可读性降低,看起来很乱。相反,我建议将return语句与res.send()分开。 @slavafomin在评论中对此做了很好的解释。

停止执行函数并同时发送响应的一种简单方法是执行

return res.send('500', 'Error message here');

这允许您使用简短if语句来处理错误,例如:

if (err) {
    return res.send('500', 'Error message here');
}

res.send函数的确切返回是一个对象似乎在结束后包含整个连接状态(请求,状态,标题等),但这应该是不重要的,因为你不会对它做任何事情。

答案 2 :(得分:0)

一个可能的解决方案是使用这个库:on-finished

var destroy = require('destroy')
var fs = require('fs')
var http = require('http')
var onFinished = require('on-finished')

http.createServer(function onRequest (req, res) {
  var stream = fs.createReadStream('package.json')
  stream.pipe(res)
  onFinished(res, () => {
    destroy(stream)
  })
})

也适用于 Express,例如:

const express = require('express');
const app = express();

app.get('/video', (req, res) => {
 const ffmpeg = spawn(ffmpegPath, argsArray);
 ffmpeg.stdout.pipe(res);
 onFinished(res, () => {
   ffmpeg.kill();
 });
});