如果这是一个多余的问题,请随时解答我.(在我询问之前,我已尽可能多地搜索)
我拼命想要了解请求/响应对象的生命周期.
请考虑以下框架代码:
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,只要任何被调用/回调/事件的任何部分都存活?
任何帮助非常感谢.谢谢阅读.
你的代码和你的假设有很多,这表明你应该学习一些JavaScript基础知识.我会推荐以下书籍:
讲述JavaScript,由Axel Rauschmayer撰写
JavaScript:The Good Parts,作者:Douglas Crockford(请注意:我不认为道格拉斯·克罗克福德所说的一切都是金色的,但我认为这本书需要阅读有抱负的JavaScript程序员)
Shelley Powers的学习节点
当然还有我自己的书,带有Node和Express的Web开发.好的,既然我已经把所有的阅读材料都拿走了,那么让我试着深入了解你的问题.
当节点接收到HTTP请求时,它创建req
和res
对象(开始他们生活的实例http.IncomingMessage
和http.ServerResponse
分别地).这些对象的预期目的是只要HTTP请求就生效.即,客户端发出一个HTTP请求,req
而res
被创建的对象,一堆东西发生,最后的一个方法res
发送的HTTP响应返回给客户端被调用,并且在该点的对象不再需要.
由于节点的异步性,可能有多个req
,并res
在任何特定时间的对象,只有在他们居住的范围来区分.这可能听起来令人困惑,但在实践中,您永远不必担心:当您编写代码时,您将其编写为就像您始终处理一个HTTP请求一样,并且您的框架(例如,Express)管理多个要求.
JavaScript确实有一个垃圾收集器,它最终在引用计数降为零后释放对象.因此,对于任何给定的请求,只要有req
对象的引用(例如),该对象就不会被释放.这是一个Express程序的简单示例,它始终保存每个请求(顺便说一下,这是一个糟糕的主意):
var allRequests = []; app.use(function(req, res, next) { allRequests.push(req); next(); });
这是一个可怕的想法的原因是,如果你永远不会删除对象allRequests
,你的服务器最终会在处理流量时耗尽内存.
通常,使用Express,您将依赖于异步函数,这些函数在完成工作后调用回调.如果回调函数具有对req
或res
对象的引用,则在异步函数完成并且回调执行(并且所有其他引用自然超出范围)之前,它们将不会被释放.这是一个只生成人为延迟的简单示例:
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中的引用计数和垃圾收集并不是您必须考虑或管理的事情.
我希望这有帮助.