有没有推荐的方法来在Node.js中创建对象?

时间:2019-07-23 22:10:04

标签: node.js object architecture request

我知道在PHP中为每个请求创建对象,并在处理完成时销毁对象。

在Java中,根据配置的不同,对象可以保留在内存中,并且可以与单个用户(通过服务器会话)相关联,也可以在多个用户之间共享。

Node.js中是否有通用规则?

我看到许多项目实例化了入口脚本中的所有应用程序对象,在这种情况下,它们将在请求之间共享。

其他人会将对象创建保留在函数中,因此AFAIK对象在处理每个请求后都会被破坏。

每种方法的缺点是什么?显然,应该考虑诸如内存使用和信息共享之类的事情,但是我们还应注意Node.js特有的其他事情吗?

1 个答案:

答案 0 :(得分:1)

JavaScript不具有绑定到给定请求的对象。当没有更多的引用并且没有代码可以到达它们时,该语言将被垃圾回收,所有对象也将被垃圾回收。这与请求处理程序绝对无关。

  

因此处理每个请求后销毁AFAIK对象。

不。 Javascript中对象的生存期与请求绝对无关。

请考虑功能范围。如果您在请求处理程序中创建一个对象并在该请求处理程序中使用它,并且不将其存储在对对象创建持久引用的位置,则就像Javascript中的任何其他函数一样,当该请求处理程序函数完成并返回时,并且不再进行任何异步操作,那么该函数中创建的任何未存储在其他范围内的对象都将被垃圾收集器清除。

与该语言中的任何其他函数调用一样,这是与请求处理程序完全相同的规则。

因此,请忘记您对PHP的任何了解,因为它的特定于请求的体系结构只会使您陷入Javascript / node.js。在node.js中没有这样的东西。

相反,可以将node.js服务器视为一个长时间运行且带有垃圾回收器的进程。当所创建的所有对象无法被实时代码访问时(例如,没有任何代码可以访问的实时引用),这些对象将被垃圾回收。无论对象是在服务器启动时,在服务器上的请求处理程序中,在服务器上的重复计时器中还是在服务器上的任何其他事件中创建的,都是相同的。该语言具有一个垃圾回收器,该垃圾回收器在任何地方都可以使用,并且对于服务器请求没有特殊行为。

在node.js服务器中执行操作的通常方法是创建对象,这些对象是请求处理程序函数(或其调用的任何函数)中的局部变量,或者有时甚至被分配为{{1}的属性}或request对象(中间件通常会这样做)。完成该函数调用后,由于所有内容都限定在请求链中的某个函数调用上,因此您在这些函数中作为局部变量创建的内容将有资格进行垃圾回收。

通常,除了有针对性的长期存储(会话状态,数据库连接或其他服务器范围的状态)外,您不会在请求处理程序之外使用许多更高范围的变量。

  

Node.js中是否有通用规则?

并不是您真正要问的那样,因为Javascript实际上只是声明变量的范围,然后从那里声明垃圾,但是我将在下面提供一些指导。

如果数据存储在高于请求处理程序的范围内(模块范围或全局范围),则它可能会持续很长时间,因为将来的请求处理程序可以访问持久引用,因此不会被垃圾回收

如果对象是在请求处理程序中创建和使用的,并且未附加到更高的范围,则在函数执行完毕后,语言将自动对其进行垃圾回收。

会话框架通常会创建一种特定的机制来存储服务器端状态,该状态会基于每个用户保留在服务器上。流行的node.js会话管理器response正是这样做的。在那里,您遵循会话框架的规则,以了解如何从每个用户的会话中存储或删除数据。这并不是真正的语言功能,因为它是使用该语言构建的特定库。甚至会话管理也依赖于垃圾收集器。需要时,数据会保留在会话管理器中,因为存在对数据的持久引用,以使其可用于将来的请求。

node.js没有诸如在语言或环境中内置的“按用户”或“按请求”数据之类的东西。会话管理器通过制作可在每个用户基础上请求或访问的持久性数据,来人为地构建“每个用户”数据。

node.js的一些一般规则:

  1. 在您的头脑和设计中定义哪些数据是特定请求处理程序的本地数据,哪些数据用于长期存储,哪些数据用于特定于用户的会话。您应该对此非常清楚。

  2. 永远不要将特定于请求的变量放在任何其他请求处理程序可以访问的更高范围内,除非这些是有目的的共享变量,可以被多个请求访问。在请求之间不小心共享变量会导致并发问题和竞态条件,并且很难跟踪服务器错误,因为一个请求可能会在执行工作时写入该变量,然后另一个请求可能也会出现并写入该变量,从而破坏了第一个请求正在处理。将这类特定于请求的变量保留在请求处理程序本地(对于请求处理程序的功能本地),这样永远不会发生。

  3. 如果要存储数据以供长期使用(超出特定请求的生存期),则通常意味着将其存储在模块范围的变量或全局范围的变量中(通常不应使用全局范围的变量) ,那么请非常小心如何存储和访问数据,以避免出现竞争情况或状态不一致,这可能会使其他一些请求处理程序对该数据的读/写混乱。 node.js使其更简单,因为它以单线程方式运行Javascript,但是一旦请求处理程序进行某种异步函数调用(如数据库调用),其他请求处理程序便会运行,因此您必须谨慎修改跨异步边界共享状态。

  

我看到许多项目实例化了入口脚本中的所有应用程序对象,在这种情况下,它们将在请求之间共享。

在使用Express框架的Web服务器的示例中,有一个express-session对象,所有请求都可以访问。唯一特定于请求的变量是由Web服务器框架创建并传递到您的请求处理程序中的apprequest对象。这些对于每个新请求都是唯一的。所有其他服务器状态均可通过所有请求访问。

  

每种方法的缺点是什么?

如果您想将Apache / PHP Web服务器模型与node.js / Express Web服务器模型进行比较,这是一个非常大的问题。它们是非常不同的体系结构,并且以前对此主题进行了广泛的讨论和辩论。我建议您在该主题上进行搜索,阅读以前写的内容,然后对您不太了解或需要澄清的事情提出更具体的问题。