我想知道以下代码行为背后的机制是什么:
res.send(200, { data: 'test data' });
console.log('still here...');
我的理解是res.send
不会返回函数,但会关闭连接/结束请求。这可以解释为什么我仍然可以在命令之后执行代码res.send
(我查看了 express 源代码,它似乎不是异步函数)。
还有什么我可能会错过的东西吗?
当然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
需要打开有效响应的方法)。
编辑:我不再做下面解释的事情,因为你不应该在不需要它时返回一个值。它使您的代码可读性降低并且看起来很hackish。相反,我建议将 return 语句与res.send()
. @slavafomin 在评论中很好地解释了这一点。
停止执行函数并同时发送响应的一种简单方法是
return res.send('500', 'Error message here');
这允许您使用简短的if
语句来处理错误,例如:
if (err) {
return res.send('500', 'Error message here');
}
该函数的确切返回是一个对象,它似乎包含您结束连接后的整个连接状态(请求、状态、标头等),但这应该不重要,因为您不会对它做任何事情。res.send
一个可能的解决方案是使用这个库: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();
});
});