Ответ 1
Node.js работает на одном потоке, в то время как языки сценариев используют несколько потоков.
Не технически. Node.js использует несколько потоков, но только один поток выполнения. Фоновые потоки предназначены для работы с IO, чтобы сделать все асинхронное добро. Эффективное управление потоками - это боль в королевстве, поэтому следующий лучший вариант - запустить в цикле событий, чтобы код мог работать, в то время как фоновые потоки блокируются в IO.
Асинхронный означает безстоящее и что соединение является постоянным, в то время как синхронный является (почти) противоположным.
Не обязательно. Вы можете легко сохранить состояние в асинхронной системе. Например, в Javascript вы можете использовать bind()
для привязки this
к функции, тем самым сохраняя состояние явно при возврате функции:
function State() {
// make sure that whenever doStuff is called it maintains its state
this.doStuff = this.doStuff.bind(this);
}
State.prototype.doStuff = function () {
};
Асинхронный означает не ждать завершения операции, а вместо этого регистрировать слушателя. Это происходит постоянно на других языках, в частности, что-то, что необходимо для ввода ввода от пользователя. Например, в графическом интерфейсе Java вы не блокируете ожидание нажатия кнопки пользователем, но вы регистрируете прослушиватель с графическим интерфейсом.
Мой второй и последний вопрос, связанный с этой темой, таков:
Может ли JavaScript быть превращен в синхронный язык?
Технически все языки синхронны, даже Javascript. Тем не менее, Javascript работает намного лучше в асинхронном дизайне, потому что он был спроектирован как однопоточный.
В основном существуют два типа программ:
- CPU bound - единственный способ ускорить его работу - увеличить время процессора
- IO bound - тратит много времени на ожидание данных, поэтому более быстрый процессор не имеет значения.
Видеоигры, числовые ключи и компиляторы связаны с ЦП, тогда как веб-серверы и графические интерфейсы обычно связаны с IO. Javascript относительно медленный (из-за его сложности), поэтому он не сможет конкурировать в сценарии с привязкой к процессору (поверьте мне, я написал свою справедливую долю связанного с CPU Javascript).
Вместо кодирования в терминах классов и объектов Javascript поддается кодированию с точки зрения простых функций, которые могут быть связаны друг с другом. Это очень хорошо работает в асинхронном дизайне, поскольку алгоритмы могут быть записаны для постепенного изменения данных процесса. IO (особенно сетевой IO) выполняется очень медленно, поэтому между пакетами данных существует довольно много времени.
Пример
Предположим, что у вас 1000 подключений в реальном времени, каждый из которых отправляет пакет каждые миллисекунды, а обработка каждого пакета занимает 1 микросекунду (очень разумно). Пусть также предполагается, что каждое соединение отправляет 5 пакетов.
В однопоточном синхронном приложении каждое соединение будет обрабатываться последовательно. Общее время (5 * 1 + 5 *.001) * 1000 миллисекунд или ~ 5005 миллисекунд.
В однопоточном асинхронном приложении каждое соединение будет обрабатываться параллельно. Поскольку каждый пакет занимает 1 миллисекунду, а обработка каждого пакета занимает 0,001 миллисекунды, мы можем обрабатывать каждый пакет соединений между пакетами, поэтому наша формула становится: 1000 *.001 + 5 * 1 миллисекунды или ~ 6 миллисекунд.
Традиционным решением этой проблемы было создание большего количества потоков. Это решило проблему ввода-вывода, но затем, когда число подключений увеличилось, так и использование памяти (потоки стоили большого объема памяти) и использование ЦП (мультиплексирование 100 потоков на 1 ядро было труднее, чем 1 поток на 1 ядре).
Однако есть и недостатки. Если вашему веб-приложению также требуется сделать тяжелый хруст, вы являетесь SOL, потому что, когда вы хрустите цифры, соединения должны ждать. Threading решает это, потому что ОС может поменять вашу интенсивную CPU задачу, когда данные готовы к потоку, ожидающему ввода IO. Кроме того, Node.js привязан к одному ядру, поэтому вы не можете воспользоваться преимуществами своего многоядерного процессора, если вы не развернете несколько экземпляров и запросы прокси.