Почему разные сессии node.js совместно используют переменные?

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

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 ответа

Решение

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++;
});

"Проблема", которую вы видите, не относится к узлу. Это просто функция определения объема в 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);

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

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

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

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

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

Другие вопросы по тегам