Подтвердить что ты не робот

Почему node.js асинхронный?

Никто не спросил об этом (из всех "предложений", которые я получаю, а также от поиска, прежде чем я спросил здесь).

Итак, почему node.js асинхронно?

Из того, что я вывел после некоторых исследований:

Языки, такие как PHP и Python, - это языки сценариев (я мог ошибаться в отношении языков, на которых написаны языки сценариев), а JavaScript - нет. (Я полагаю, это связано с тем, что JS не компилируется?)

Node.js работает на одном потоке, в то время как языки сценариев используют несколько потоков.

Асинхронный означает безстоящее и что соединение является постоянным, в то время как синхронный является (почти) противоположным.

Возможно, ответ найден где-то выше, но я все еще не уверен.

Мой второй и последний вопрос, связанный с этой темой, таков:

Может ли JavaScript быть превращен в синхронный язык?

PS. Я знаю, что некоторые из вас спросят: "Почему вы хотите сделать JS синхронным?" в ваших ответах, но правда в том, что я этого не делаю. Я просто задаю эти типы вопросов, потому что я уверен, что там больше людей, чем я сам, которые думали о таких вопросах.

4b9b3361

Ответ 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 привязан к одному ядру, поэтому вы не можете воспользоваться преимуществами своего многоядерного процессора, если вы не развернете несколько экземпляров и запросы прокси.

Ответ 2

Javascript не компилируется ни во что. Он "оценивается" во время выполнения, как PHP и Ruby. Поэтому это скриптовый язык, как PHP/Ruby. (это официальное название - фактически ECMAScript).

"Модель", которой придерживается Node, немного отличается от PHP/Ruby. Node.js использует "цикл событий" (единственный поток), который имеет одну цель - принимать сетевые запросы и обрабатывать их очень быстро, и по какой-либо причине он сталкивается с операцией, которая занимает некоторое время (запрос API, запрос базы данных - в основном что-либо, связанное с IO (input/output)), оно передает это в фоновый "рабочий" поток и уходит, чтобы сделать что-то еще, пока рабочий поток ждет завершения длинной задачи. Когда это произойдет, основной "цикл событий" примет результаты и продолжит работать с ними.

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

Асинхронный означает безстоящий и что соединение является постоянным в то время как синхронный является (почти) противоположным.

Нет. Синхронные инструкции завершаются в натуральном порядке, от первого до последнего. Асинхронные инструкции означают, что если шаг в потоке программы занимает относительно много времени, программа продолжит выполнение операций и просто вернется к этой операции по завершении.

Может ли JavaScript быть превращен в синхронный язык?

Некоторые операции в JavaScript являются синхронными. Другие асинхронны. Например:


Операции блокировки:

for(var k = 0; k < 1; k = k - 1;){
  alert('this will quickly get annoying and the loop will block execution')
alert('this is blocked and will never happen because the above loop is infinite');

Асинхронный:

jQuery.get('/foo', function (result) { alert('This will occur 2nd, asynchronously'); });
alert('This will occur 1st. The above operation was skipped over and execution continued until the above operation completes.');

Ответ 3

Может ли JavaScript быть превращен в синхронный язык?

Javascript не является "асинхронным языком"; скорее, node.js имеет много асинхронных API. Асинхронность - это свойство API, а не языка. Легкость, с которой функции могут быть созданы и переданы в javascript, позволяет удобно передавать функции обратного вызова, что является одним из способов обработки потока управления в асинхронном API, но по сути нет асинхронного в javascript. Javascript может легко поддерживать синхронные API.

Почему node.js асинхронный?

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