2015-01-20 4 views
0

Я пишу приложение React (Экспресс-сервер), который отображает на сервере клиента + с использованием общей ('изоморфной') кодовой базы. В некоторых случаях, когда сервер является средством визуализации, я хочу получить доступ к объекту запроса, не передавая его по всему месту. Поскольку узел отвечает на один запрос за раз, небезопасно ли использовать кеширование переменной, не забудьте сбросить ее перед отправкой ответа?Избегайте пролета вокруг объекта запроса

Это работает, но может кто-то сказать мне, почему это либо хорошо или плохая идея? ...

server.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; }; 

resolve.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(); 
    } 
    } 
}; 

ответ

2

Но что произойдет, если вы получите два одновременных запроса от разных пользователей? Первый запрос будет кэшироваться, а второй будет перезаписывать запрос первого пользователя. Между тем предположим, что вы выполняли несколько операций ввода-вывода и нуждались в доступе к запросу после его завершения, тогда объект запроса первого пользователя уже был бы перезаписан вторым запросом пользователя. В целом, это очень опасно. Лучшим способом было бы использовать какое-то хранилище в хранилище ключей памяти, но вам все равно нужно каким-то образом обойти ключ.

+0

Если это случай, тогда да, это не сработает. Так можно ли выразить для обработки другого запроса до того, как он выдает предыдущие res? – ndreckshage

+0

Конечно, предположим, что у вас есть запрос к базе данных, который требует секунд для обработки, поскольку узел является асинхронным, что операция db не блокирует выполнение последующих запросов. –

+0

Хорошо, как я экспериментировал с этим было несколько вкладок, открытых в Chrome, которые, по-видимому, ждут отправки следующего запроса на тот же URL-адрес, пока не вернется первый. Вот почему я был в замешательстве. Проверяя это с помощью нескольких браузеров + сканер apache, я отчетливо вижу проблему. Благодарю. – ndreckshage

2

Дано Node однопоточное, и вы не : для выполнения любых операций ввода-вывода, то да, ваш код выглядит безопасным для меня. Express будет запускать все промежуточное программное обеспечение синхронно, поэтому к моменту вашего обещания (как и синхронно) 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 }); 
    }); 
}); 

resolve.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(); 
    } 
    } 
}; 
+0

nvm я видел проблему, когда я пробовал эту скамку apache + параллелизм – ndreckshage

+0

@ndreckshage увидел, какую проблему? – James

+0

То, что несколько запросов происходили сразу. Экспериментировал с setTimeout (разрешение, 5000) в файле resol.js и консоль зарегистрировал запрос # + ответ #. Путаница, потому что я ударил страницу в хром на 10 вкладках одновременно, а запросы/ответы регистрировались в последовательном порядке (req, res, req, res, req, res). Тестирование с помощью apache bench + concurrency, я видел запросы, которые были записаны вместе (req, req, req, res, res, res). – ndreckshage