0

我正在编写一个 React 应用程序(Express 服务器),它使用共享(“同构”)代码库在客户端 + 服务器上呈现。在某些情况下,当服务器是渲染器时,我想访问请求对象,而不必到处传递它。由于节点一次响应一个请求,利用缓存变量是否安全,确保在发送响应之前重置它?

这行得通,但有人能告诉我为什么这是一个好主意或坏主意吗?...

服务器.js

var r = require('./request-store');
app.use(function(req, res, next) {
  r.set(req);
  next();
});

var resolve = require('./resolve');
// ...deferring to react router for client / server routing
app.use(function(req, res) {
  resolve().then(function(data) {
    r.set(null);
    res.render('index', { data: data });
  });
});

请求-store.js

var r = null;
module.exports.set = function(req) { r = req; };
module.exports.get = function() { return r; };

解决.js

var r = require('./request-store');
module.exports = function() {
  return new Promise(resolve, reject) {
    if (isServer) {
      console.log(r.get());
      resolve();
    } else if (isClient) {
      resolve();
    }
  }
};
4

2 回答 2

2

但是,如果您同时收到来自不同用户的两个请求,会发生什么?第一个请求将被缓存,第二个请求将覆盖第一个用户的请求。同时假设您正在执行一些 IO 并且需要在完成后访问请求,那么第一个用户的请求对象将已经被第二个用户的请求覆盖。总的来说,这样做是非常危险的。最好的方法是使用某种内存键值存储,但您仍然需要以某种方式传递密钥。

于 2015-01-20T16:11:56.350 回答
2

鉴于 Node 是单线程的,并且您似乎没有执行任何 I/O,那么是的,您的代码对我来说看起来很安全。Express 将同步运行所有中间件,因此在您的 Promise 运行时(因为它也是同步的)r.get()应该返回正确的请求对象。

但是,我不确定您是否需要缓存它,您可以将它直接传递给resolve并使用闭包在您的承诺中捕获它

var resolve = require('./resolve');
// ...deferring to react router for client / server routing
app.use(function(req, res) {
    // pass 'req' into `resolve`
    resolve(req).then(function(data) {
        r.set(null);
        res.render('index', { data: data });
    });
});

解决.js

var r = require('./request-store');
module.exports = function(req) {
  // capture 'req' for use later
  return new Promise(resolve, reject) {
    if (isServer) {
      console.log(req);
      resolve();
    } else if (isClient) {
      resolve();
    }
  }
};
于 2015-01-20T16:43:34.553 回答