在2条路线之间共享变量

时间:2018-06-20 21:32:28

标签: node.js express

我想知道是否有一种方法可以在expressJS中的2条路由之间共享变量而不将其声明为全局变量。考虑我有以下路线:

exports.routeOne = (req,res) => { 
 var myVariable='this is the variable to be shared';
}

exports.routeTwo = (req,res) => {
  //need to access myVariable here
}

这怎么办?

3 个答案:

答案 0 :(得分:0)

===============

注意

此答案回答的是错误的问题,但对于像我一样误解了该问题的其他人可能仍然有用,所以我暂时将其保留在这里。

===============

要使变量存在,必须先执行mod_alias,然后再执行routeOne。这是Express的一种非常常见的情况。要了解有关其工作原理的详细信息,请阅读中间件(http://expressjs.com/en/guide/writing-middleware.html),并了解每条路由都是中间件。

此处常见的模式解决方案是向存储变量的routeTworeq对象添加新属性。然后,您告诉路由来调用下一个中间件。下一个中间件可以访问相同的resreq,因此它也可以访问您刚刚存储的属性和值。

这种做法没有错,因为大多数中间件都这样做。例如,body-parser中间件(https://www.npmjs.com/package/body-parser)。

以下是代码运行方式的示例:

routes.js

res

index.js

exports.routeOne = (req,res,next) => { 
 req.myVariable='this is the variable to be shared'
 next()
}

exports.routeTwo = (req,res) => {
  //need to access myVariable here
  console.log(req.myVariable)
}

答案 1 :(得分:0)

NodeJS令人敬畏的一件事就是您可以将状态存储在变量中。运行NodeJS服务器的进程将继续运行,而不会为传入的每个请求重新启动。因此,使用GLOBAL.myVarName存储的任何变量或存储在模块范围内的变量(单个JavaScript文件)都将保留。 ..直到该过程退出。如果服务器关闭或抛出未捕获的错误或其他异常,则该过程可能会退出。您可以设置一个流程管理器以使其继续运行,但是您的内存变量现在丢失了。

我建议使用范围较高的变量进行缓存,但是如果数据很重要,则应根据需要将其存储到数据库或从中读取。

这是您的 routes.js 模块的示例。您在函数外部声明的任何变量都将作用于此文件。换句话说,变量是该文件的全局变量。您可以在https://nodejs.org/dist/latest-v8.x/docs/api/modules.htmlhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures上阅读更多内容。

routes.js

let variableScopedToModule = 0

exports.routeOne = (req, res) {
  variableScopedToModule++
}

exports.routeTwo = (req, res) {
  console.log(variableScopedToModule)
}

如果绝对不要丢失变量状态很重要,并且假设您没有在多个进程上运行服务器以实现负载平衡,那么可以执行以下操作:

routes.js

const db = require('./my-db-controller')

let cachedValue

exports.routeOne = async (req, res) {
  if (cachedValue === undefined) cachedValue = await db.getValue()
  cachedValue++
  db.setValue(cachedValue)
}

exports.routeTwo = (req, res) {
  console.log(cachedValue)
}

第二种解决方案更加复杂,因为您需要了解promises以及asyncawait。同样,如果您使用负载平衡器,则除非使用Redis之类的方法,否则该解决方案将无法工作。另外,您也可以为每个请求读写数据库,而不是在内存缓存中使用。

答案 2 :(得分:0)

对于要在一个请求到另一个请求之间保留的特定于用户的数据,您不能仅将数据存储在简单的服务器端变量中,因为服务器端变量是在请求服务器的所有用户之间自由共享的

存储特定于用户的服务器端数据的通常方法是使用会话对象。简而言之,当用户发出请求时,某些会话中间件(在每个请求上运行)都会检查会话cookie是否存在。如果没有,则创建一个。会话cookie服务器在将来发出请求时可以唯一地标识该特定用户。

一旦有了唯一的会话cookie,会话中间件就可以创建一个与该会话cookie对应的会话对象。通常,会话cookie中有一个唯一的ID,该ID用作会话对象的查找键。

现在,每当该用户向您的服务器发出请求时,会话中间件都会查看会话cookie,从中获取加密的会话ID,解密该ID,查找与该ID对应的会话对象,然后通常在req.session中使该会话对象可用于您的请求处理程序。这样,您的请求处理程序就可以完全访问会话对象,并且可以在该会话对象上添加,删除或修改您自己的属性。

express-session是常见的中间件,用于通过nodejs / express实现会话。在文档中有很多关于如何使用它的示例,因此在此我将不再重复。这是one such example in the doc

默认情况下,express-session使用内存存储(这意味着会话对象保留在内存中)。这对于简单的使用来说可能很好,但是它有一些局限性,快速会话不建议将其用于生产。将会话保留在内存中的一个主要限制是,如果服务器崩溃或重新启动,则所有会话数据都会丢失。有数十种用于快速会话的外接程序对象存储,其中大多数持久存储数据,例如磁盘上的数据库。