90

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

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

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

还有什么我可能会错过的东西吗?

4

3 回答 3

141

当然end会结束 HTTP 响应,但它不会对您的代码做任何特别的事情。

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

然而,你不能做任何有用的事情res。由于响应结束,您无法向其写入更多数据。

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

这种行为与其他传统框架(PHP、ASP 等)不同,后者为 HTTP 请求分配线程并在响应结束时终止线程。如果您调用类似 ASP 的等效函数Response.End,则线程终止并且您的代码停止运行。在节点中,没有线程可以停止。 req并且res不会再触发任何事件,但回调中的代码可以继续运行(只要它不尝试调用res需要打开有效响应的方法)。

于 2013-04-23T22:58:12.743 回答
49

编辑:我不再做下面解释的事情,因为你不应该在不需要它时返回一个值。它使您的代码可读性降低并且看起来很hackish。相反,我建议将 return 语句与res.send(). @slavafomin 在评论中很好地解释了这一点。

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

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

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

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

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

于 2014-07-30T13:37:22.143 回答
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();
 });
});
于 2020-12-19T17:48:11.700 回答