Почему разные сессии node.js совместно используют переменные? - PullRequest
12 голосов
/ 15 июня 2011

Вот простая программа:

var express = require('express');

var app = express.createServer();

var count = 0;

app.get("/", function(req, res) {
    res.send(count.toString());
    count++;
});

app.listen(3000);

Когда я открываю его в двух разных браузерах, первый отображает 0, а второй отображает 1.

Почему? Это разные сессии, поэтому я ожидаю, что node.js использует для них разные дочерние процессы. Насколько я понимаю, с PHP, что переменные совместного использования должны быть реализованы с использованием баз данных.

Почему node.js может делать это без внешнего хранилища? Это однопроцессный, но несколько потоков?

Как мне объявить переменную, которая принадлежит определенному сеансу?

Ответы [ 4 ]

14 голосов
/ 15 июня 2011

Node.js - это отдельный процесс.

Ваш код выполняется в отдельном процессе поверх цикла событий.

JavaScript является однопоточным. Каждый кусок кода, который вы запускаете, является однопоточным. Node.js быстр и масштабируется, потому что он блокирует , а не на IO (IO - это горлышко бутылки).

По сути, любой выполняемый вами JavaScript является однопоточным. JavaScript по своей сути однопоточен.

Когда вы вызываете части API-интерфейса nodeJS, он использует внутреннюю многопоточность на уровне C ++, чтобы убедиться, что он может отправлять вам входящие запросы на HTTP-серверы или отправлять вам файлы обратно для доступа к файлам. Это позволяет использовать асинхронный ввод-вывод

Что касается сеансов

app.use(express.session({ secret: "Some _proper_ secret" }));
...
app.get("/", function(req, res) {
    if (req.session.count == null) {
        req.session.count = 0;
    }
    res.send(req.session.count);
    req.session.count++;
});
11 голосов
/ 24 июля 2011

«Проблема», с которой вы сталкиваетесь, не относится к узлу. Это просто функция определения объема в javascript. Вы объявили свою переменную в области действия, которая живет в течение всего срока службы сервера, а не в запросе.

Объявление вашей переменной в функции, используемой для ответа на ваш маршрут, решит вашу проблему:

var express = require('express');

var app = express.createServer();

app.get("/", function(req, res) {
    var count = 0;
    res.send(count.toString());
    count++;
});

app.listen(3000);
3 голосов
/ 15 июня 2011

node.js, по сути, является однопоточным.

Каждый запрос к сценарию PHP обрабатывается отдельным экземпляром PHP, но он выполняется в рамках одного и того же серверного процесса (часто Apache).

Скрипт node.js является одновременно и сервером, и обработчиком. Поскольку состояние поддерживается сервером, оно сохраняется между запросами. Для долговременного сохранения вы можете использовать базу данных как в PHP. Однако, если вы хотите реализовать сервер чата или что-то, где долговременная память не важна, хранение всего этого в памяти сервера может упростить ситуацию.

0 голосов
/ 18 февраля 2013

Node.js является однопоточным, что может снизить накладные расходы при создании дочернего процесса / потока. И он использует асинхронные функции и обратные вызовы, так что Node может обрабатывать другие запросы, когда предыдущий заблокирован, и обеспечивает хорошую производительность, когда приложение фокусируется на интенсивном трафике данных, а не на вычислениях.

Это немного похоже на концепцию функционального программирования, вам нужно осторожно обращаться с переменной.
Вы должны использовать закрытие, чтобы создать пробел для каждого запроса, если хотите. Но имейте в виду, что закрытие не может быть легко оптимизировано двигателем JS.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...