Як NodeJS може бути "не блокуючим"?


14

Я вивчаю NodeJS і просто хотів щось уточнити. У кількох вступних навчальних посібниках і книгах до цього часу дуже рано вони описали "неблокуючу" архітектуру Node, а точніше, що можна (і рекомендується, вся точка) кодувати без блокування.

Так, наприклад, цей приклад був наведений у книзі, яку я читаю асинхронним способом отримання даних із бази даних.

http.createServer(function (req, res) {
  database.getInformation(function (data) {
      res.writeHead(200);
      res.end(data);
  });
});

Що відбувається (наскільки я це розумію) - Node здійснює виклик до бази даних, після чого продовжує обробляти все, що може бути наступним у стеці викликів. Коли запит на базу даних буде завершений, змінна даних у функції анонімного виклику буде заповнена, і ця функція буде додана до стеку викликів (і згодом виконується, коли Node потрапляє до неї).

Моє запитання, що саме обробляє запит бази даних? Безумовно, Вузол повинен блокувати, поки це робить? Що стосується запиту бази даних? Або якщо Node чекає на асинхронний HTTP GET-запит на зовнішній ресурс, що дбає про цей запит, що дозволяє Node продовжувати обробляти стек виклику і бути "не блокуючим"?

Відповіді:


17

Коли Node.js описується як "неблокуючий", це конкретно означає, що його IO не блокує. Node використовує libuv для обробки свого IO платформо-агностичним способом. У Windows він використовує порти завершення вводу-виводу, в Unix використовує epoll / kqueue / select / і т.д. Таким чином, він робить не блокуючий запит вводу-виводу (який може мати моніторинг фонових потоків, але він ніколи не піддається впливу JavaScript), і в результаті він виводить його в черговий цикл подій, який викликає зворотний виклик JavaScript в основному (читайте: лише) потоки JavaScript.

Для баз даних це залежить від того, як записана бібліотека. Якщо він використовує HTTP для зв'язку (як це роблять деякі бази даних NoSQL), він може бути легко записаний у чистому JavaScript, використовуючи стандартну httpбібліотеку вузлів . Якщо це робиться іншим способом, ну це залежить від бібліотеки. Це може бути написано на C / C ++ і використовувати фонові нитки, доки ця абстракція ніколи не піддається впливу JavaScript.

Що стосується вашого питання про те, що таке "обробка" запиту бази даних, в ідеалі все, що потрібно зробити, це надсилання простого повідомлення в бібліотеку (наприклад, оператор SQL або якийсь інший запит або запит на підключення), і в цей момент ваш JavaScript продовжує чубати. Коли бібліотека готова відправити повідомлення назад, вона посилає повідомлення назад до черги подій вузла, яка запускає зворотний виклик, дозволяючи виконувати цей фрагмент коду.


Є netпакет, коли http недоступний.
Флоріан Маргаїн

Деталі, які можуть допомогти. Вузол використовує двигун V8 JS. Однією з найкращих особливостей V8 є простота прив’язки процесів C / C ++ до дзвінків JS. Функції JavaScript блокуються, але все, що функція, це викликати щось під кришкою, яке не блокується. Потім інша функція JS відповідає, коли цей процес виконаний. Функції JS, що блокують один одного, означають, що ви ніколи не будете намагатися зробити щось подібне, як запланувати запис в одне і те ж розташування файлу одночасно, і там я маю на увазі багатопотокове управління. Завжди зрозуміло, який запит з’явився першим з метою складання черги.
Ерік Реппен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.