javascript - 使用回调时的 express.js 请求/响应对象生命周期

标签 javascript express callback garbage-collection lifecycle

如果这是一个多余的问题,请随时帮我解决。 (忍不住搜索了再问)

我拼命想了解请求/响应对象的生命周期。

考虑以下框架代码:

app.get('/', function(req, res) {

  var setCookie = function(err, idCookie) { //callback after cookieSearch in DB
    // ... do something with the result of findCookieInDatabase() (handle error, etc.);
    res.sendfile('index.html');
  }

  var cookie = parseCookie(req.get('Cookie')); //parse and format cookie

  findCookieInDatabase(cookie, afterCookieSearch); //tries to find cookie is DB


  // .. do some content return stuff, etc.
}

(请注意原始代码做的更多,例如检查“Cookie”是否存在等)

我知道 req 和 res 对象被创建并且必须在某个时候被垃圾收集。 (希望如此)

当使用 setCookie 作为参数调用 findCookieInDatabase() 时,我假设 setCookie 当时只是一个字符串(包含该函数)并且不会被解析或执行,直到在 findCookieInDatabase 中遇到回调(setCookie)语句().

我也明白,由于我不了解 javascript 回调的核心,所以我的上述假设可能是完全错误的。 (我也对此进行了很多搜索,但我所能找到的只是关于如何使用回调的无穷无尽的教程。没有关于引擎盖下的内容)

所以问题是: javascript(或 node.js)如何知道让“res”保持事件状态多长时间以及何时可以对其进行垃圾回收?

setCookie 中的 res.sendfile 行是否实际上作为一个事件引用,因为它是通过 findCookieInDatabase() 调用的?

javascript 是否真的跟踪所有引用并保持 req 和/或 res 存活,只要任何被调用/回调编辑/事物的任何部分都活着?

非常感谢任何帮助。感谢阅读。

最佳答案

您的代码和您的假设发生了很多变化,这表明您应该学习一些 JavaScript 基础知识。我会推荐以下书籍:

当然还有我自己的书,Web Development with Node and Express .好吧,现在我已经把所有的阅读 Material 都拿走了,让我试着触及你问题的核心。

当 Node 接收到 HTTP 请求时,它会创建 reqres 对象(它们作为 http.IncomingMessagehttp.ServerResponse 分别)。这些对象的预期目的是它们与 HTTP 请求一样长。也就是说,客户端发出 HTTP 请求,创建了 reqres 对象,发生了一堆事情,最后是 res 上的一个方法> 被调用将 HTTP 响应发送回客户端,此时不再需要对象。

由于 Node 的异步特性,在任何给定时间都可能有多个 reqres 对象,仅通过它们所在的范围来区分。这听起来可能令人困惑,但在实践中,您永远不必担心这一点:当您编写代码时,您编写它就像您总是处理一个 HTTP 请求,而您的框架(例如 Express)管理多个请求。

JavaScript 确实有一个垃圾收集器,它最终会在引用计数降为零后释放对象。因此对于任何给定的请求,只要存在对 req 对象的引用(例如),该对象就不会被释放。这是一个总是保存每个请求的 Express 程序的简单示例(顺便说一句,这是一个糟糕的想法):

var allRequests = [];
app.use(function(req, res, next) {
    allRequests.push(req);
    next();
});

之所以这是一个糟糕的想法,是因为如果您从不从 allRequests 中删除对象,您的服务器最终会在处理流量时耗尽内存。

通常,对于 Express,您将依赖异步函数,这些函数在完成工作后会调用回调。如果回调函数有对 reqres 对象的引用,它们将不会被释放,直到异步函数完成并且回调执行(并且所有其他引用都不在范围,自然)。这是一个简单的例子,它只是产生了一个人为的延迟:

app.get('/fast', function(req, res) {
    res.send('fast!');
});

app.get('/slow', function(req, res) {
    setTimeout(function() {
        res.send('sloooooow');
    }, 3000);
});

如果您导航到 /slow,您的浏览器将旋转 3 秒。在另一个浏览器中,如果你多次访问 /fast,你会发现它仍然有效。这是因为 Express 会为每个请求创建一个 reqres 对象,它们之间不会相互干扰。但是与 /slow 请求关联的 res 对象没有被释放,因为回调(持有对该实例的引用)尚未执行。

归根结底,我觉得你想多了。了解基础知识固然很好,但在大多数情况下,JavaScript 中的引用计数和垃圾收集不是您必须考虑或管理的事情。

希望对您有所帮助。

关于javascript - 使用回调时的 express.js 请求/响应对象生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24398264/

相关文章:

Node.js 已停止上传

node.js 检查 mongoose 中的重复值

javascript 发送参数对象作为参数

javascript - 参数化ajax请求正文

javascript - 简单的书签不适用于 chrome

javascript - 通过 WebCryptoAPI 而不是浏览器化 Node 加密模块在浏览器中生成 ECDH key

node.js - 在 aws elastic-beanstalk 上使用 Express 配置 https

ruby-on-rails - 在 rails3 中使用观察者自定义回调

javascript - 为什么 javascript 回调是异步的?

javascript - 是否可以暂停/挂起(不要在套接字上接受(2))Node.js 服务器?