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

 阳光-假日 发布于 2023-01-07 18:29

如果这是一个多余的问题,请随时解答我.(在我询问之前,我已尽可能多地搜索)

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

请考虑以下框架代码:

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()中遇到callback(setCookie)语句之前不会被解析或执行.

我也明白,我可能完全错误的上述假设,这可能是由于我对javascript回调的胆量缺乏了解.(我在这方面也进行了很多搜索,但我发现的是如何使用回调的无穷无尽的东西.没有什么在引擎盖下)

所以问题是:javascript(或node.js)如何知道保持'res'活着多久以及什么时候可以垃圾收集呢?

setCookie中的行res.sendfile是否实际上充当了活动引用,因为它是通过findCookieInDatabase()调用的?

javascript是否实际上跟踪所有引用并保持req和/或res,只要任何被调用/回调/事件的任何部分都存活?

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

1 个回答
  • 你的代码和你的假设有很多,这表明你应该学习一些JavaScript基础知识.我会推荐以下书籍:

    讲述JavaScript,由Axel Rauschmayer撰写

    JavaScript:The Good Parts,作者:Douglas Crockford(请注意:我不认为道格拉斯·克罗克福德所说的一切都是金色的,但我认为这本书需要阅读有抱负的JavaScript程序员)

    Shelley Powers的学习节点

    当然还有我自己的书,带有Node和Express的Web开发.好的,既然我已经把所有的阅读材料都拿走了,那么让我试着深入了解你的问题.

    当节点接收到HTTP请求时,它创建reqres对象(开始他们生活的实例http.IncomingMessagehttp.ServerResponse分别地).这些对象的预期目的是只要HTTP请求就生效.即,客户端发出一个HTTP请求,reqres被创建的对象,一堆东西发生,最后的一个方法res发送的HTTP响应返回给客户端被调用,并且在该点的对象不再需要.

    由于节点的异步性,可能有多个req,并res在任何特定时间的对象,只有在他们居住的范围来区分.这可能听起来令人困惑,但在实践中,您永远不必担心:当您编写代码时,您将其编写为就像您始终处理一个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正在为每个请求创建一个req和一个res对象,其中没有一个会相互干扰.但是res/slow请求关联的对象未被释放,因为回调(持有对该实例的引用)尚未执行.

    在一天结束的时候,我觉得你是在过度思考.当然,了解基础知识是件好事,但在大多数情况下,JavaScript中的引用计数和垃圾收集并不是您必须考虑或管理的事情.

    我希望这有帮助.

    2023-01-07 18:32 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有