Как неблокирующий ввод / вывод работает с каналами - PullRequest
0 голосов
/ 08 мая 2018

Я хочу знать, как движок в node.js знает, когда вызывать и выполнять операцию с очередями.Я понимаю, что node.js является однопоточным и использует асинхронную неблокировку для выполнения операций.

Но давайте представим, что вы что-то вызываете из базы данных, а node.js ставит эту операцию в очередь и не ждет, пока это произойдет.выполнить дальнейшие строки кода.Будучи одним потоком, он сохраняет данные в каналах (если я не ошибаюсь).Но как сервер узнает, что сеть не занята, и это подходящее время для выполнения операции с очередями.

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

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

Узел внутренне использует базовые операционные системы, не блокирующие API-интерфейсы io. См. overlapped io, WSAEventSelect для Windows, select для Linux.

0 голосов
/ 08 мая 2018

Непонятно, что вы подразумеваете под "каналами", поскольку это не встроенная концепция node.js или термин, который используется внутри для описания работы node.js. Учебник , на который вы ссылаетесь в своем комментарии, говорит о языке Java, а не о языке Javascript, поэтому он не имеет абсолютно никакого отношения к node.js. Концепция «каналов» в этом руководстве - это то, что конкретная библиотека NIO реализует в Java.

Но, если вы действительно просто спрашиваете, как работают асинхронные операции в node.js, я могу объяснить эту общую концепцию.

node.js работает с очередью событий. Интерпретатор node.js получает следующее событие в очереди событий и выполняет его (обычно это включает вызов функции обратного вызова). Эта функция обратного вызова выполняется (однопоточная), пока не вернется. Когда он возвращается, интерпретатор node.js затем ищет в очереди событий следующее событие. Если они есть, он захватывает это следующее событие и вызывает обратный вызов, связанный с ним. Если в очереди событий в данный момент нет событий, он ожидает, когда событие будет помещено в очередь событий (при этом ничего не нужно делать, возможно, выполняется сборка мусора).

Теперь, когда вы выполняете какую-то асинхронную операцию в своем Javascript (например, запрос к БД), вы можете использовать функцию запроса к БД, которая инициирует запрос (отправляя запрос в базу данных), а затем немедленно возвращается. Это позволяет вашему куску Javascript, который запустил этот запрос, затем вернуться и вернуть управление узлу node.js.

Между тем, некоторый нативный код управляет соединением с вашей базой данных. Когда ответ возвращается из базы данных, событие добавляется во внутреннюю очередь событий node.js.

Всякий раз, когда интерпретатор node.js заканчивает запуск другого Javascript, он просматривает очередь событий, вытаскивает следующее событие и вызывает связанный с ним обратный вызов. Таким образом, ваш запрос к БД обрабатывается вашим кодом. Во всех случаях здесь асинхронная операция имеет своего рода обратный вызов, который интерпретатор может вызвать, когда находит событие в очереди событий.

Будучи однопоточным, он сохраняет данные в каналах (если я не ошибаюсь).

node.js не имеет концепции "каналов", поэтому я не уверен, что вы имели в виду.

Или он выполняет операцию с очередями в конце программы.

Когда результат возвращается из базы данных, некоторый собственный код управления, который вставит событие в очередь событий node.js. Интерпретатор Javascript будет обслуживать это событие, затем в следующий раз он вернется к циклу событий (другой Javascript завершил работу и пришло время проверить следующее событие для обработки).

Важно понимать, что инициирование асинхронной операции неблокирует, поэтому вы получите следующее:

console.log("1");
callSomeAsyncFunction(someData, (err, data) => {
    // this callback gets called later when the async operation finishes
    // and node.js gets a chance to process the event that was put
    // in the event queue by the code that managed the async operation
    console.log("2");
});

// right here there is nothing else to do so the interpreter returns back
// to the system, allowing it to process other events
console.log("3");

Из-за неблокирующей природы вещей, это будет записывать:

1
3
2

Некоторые другие ссылки по теме:

Как JavaScript обрабатывает ответы AJAX в фоновом режиме?

Где находится очередь событий node.js?

Понимание обратного вызова

Почему цикл while блокирует цикл событий узла?

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