我想知道以下代码行为背后的机制是什么:
res.send(200, { data: 'test data' });
console.log('still here...');
我的理解是res.send
不返回该函数,但关闭连接/结束请求。这可以解释为什么我仍然可以在res.send
命令后执行代码(我查看了快速源代码并且它似乎不是异步函数)。
还有什么东西在玩,我可能会失踪吗?
答案 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
之类的等效函数,则线程终止并且代码停止运行。在节点中,没有要停止的线程。 req
和res
不会再触发任何事件,但回调中的代码可以自由继续运行(只要它不会尝试调用需要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();
});
});