ru:https://highload.today/blogs/eto-ogromnyj-probel-u-bolshinstva-razrabotchikov-6-glavnyh-voprosov-na-sobesedovanii-po-node-js/ ua:https://highload.today/uk/blogs/shho-take-event-loop-v-node-js/
logo
Back-end      14/12/2022

«Це величезна прогалина у більшості розробників»: 6 головних питань на співбесіді з Node.js

Владислав Хирса BLOG

Senior Backend Developer | Node.js | NestJS | Express.js | SQL | NoSQL | AWS

Що таке цикл подій, як він працює і чому про нього всі завжди питають на співбесідах? Певний час я не міг чітко відповісти на це питання, а вже потім, коли з часом набрався досвіду і сам почав наймати людей, то стало зрозуміло, що це реально велика прогалина у більшості JavaScript-розробників.

1Що таке Event Loop в Node.js

Event Loop — це цикл, за допомогою якого Node.js має змогу виконувати неблокуючі операції I/O — input/output.

І ще є дуже важливим, що Event Loop — це тільки «серце» великого механізму відомої бібліотеки libuv. Все, що потрібно знати про libuv, я описав у своїй статті «Фундамент для JavaScript-розробника: як відповісти, що таке libuv на співбесіді з Node.js».

Тож зараз ми розглянемо, що всередині Event Loop:

Фази — те, про що далеко не всі знають або говорять, але знання фаз і є фундаментом для розуміння послідовності виконання коду, написаного на JavaScript.

2 Розкажіть про фази

  • Timers: фаза, в якій виконуються колбеки, заплановані setTimeout() і setInterval().
  • Pending callbacks: виконує I/O-колбеки, які були відкладені до наступної ітерації циклу.
  • Idle, prepare: використовувати тільки внутрішньо.
  • Poll: отримання нових подій I/O; виконувати колбеки, пов’язані з I/O (майже всі, за винятком колбеків, які виконуються в фазі close callbacks, запланованих таймерами та setImmediate()); при необхідності node може тут блокуватися.
  • Check: тут викликаються setImmediate() callbacks.
  • Онлайн-курс "Маркетингова аналітика" від Laba.
    Опануйте інструменти для дослідження ринку й аудиторії та проведення тестувань.Дізнайтесь, як оптимізувати поточні рекламні кампанії та будувати форкасти наступних.
    Детальніше про курс
  • Сlose callbacks: закриває колбеки такі як socket/http/eventEmitter/.on(‘close', () =>).

З повною інформацією про фази можна ознайомитися тут.

3Що таке мікро- та макрозадачі

Тож після запитань «що таке Event Loop» і «що ви знаєте про фази»  запитують, чи знаєте ви, що таке мікрозадачі та макрозадачі, у відповідь на це запитання у мене також є стаття.

А зараз ми розберемо наступне:

  • різницю між setTimeout() i setImmediate();
  • різницю між process.nextTick() і setImmediate();
  • які труднощі можливо вирішити за допомогою process.nextTick().

4У чому різниця між setTimeout() i setImmediate()

setTimeout() — колбек, який ми передаємо в таймер, виконується після певного пройденого часу, переданого другим аргументом в setTimeout() або при відсутності вказаного часу, за замовчуванням через 4 мс.

setImmediate() виконується після поточної poll-фази:

Онлайн-курс "Комунікаційний менеджер" від Skvot.
Ви отримаєте скіли комунікації, сформуєте CV та розробите власну one page strategy. Для своєї карʼєри та успішного масштабування бренду.
Програма курсу і реєстрація
const fs = require('fs');

fs.readFile(__filename, () => {
  setTimeout(() => {
    console.log('Timeout');
  }, 0);
  setImmediate(() => {
    console.log('Immediate');
  });
});

Результат:

Immediate
Timeout

Але що є важливим, що залежно від контексту, в якому знаходяться функції, впливає на те, чій колбек буде виконаний першим.

Коли ми використовуємо обидва таймера в логіці, яка працює з I/O, як в прикладі зверху, то setImmediate() буде завжди першим при умові, що передані в них колбеки будуть схожі за логікою або однакові.

setTimeout(() => {
  console.log('timeout');
}, 0);
setImmediate(() => {
  console.log('immediate');
});

В іншому випадку таймери будуть виконуватись непередбачувано. Нижче результат двух запусків таймерів:

Immediate
Timeout
Timeout
Immediate

5У чому різниця між process.nextTick() і setImmediate()

В цій ситуації завжди першим виконується process.nextTick(), він виконується при наступному тіку (tick) ядра вашого комп’ютера, а це 100-1000 тіків за секунду — і в цьому його небезпека.

Якщо ви написали рекурсивну функцію і там є process.nextTick(), то поточний цикл Event Loop так може і не завершитись, про це є застереження в офіційній документації.

6Які труднощі можливо вирішити за допомогою process.nextTick()

Є такі ситуації, коли нам треба виконати нашу функцію з мінімальною затримкою лише після того, як код буде ініціалізовано, але ще жодна I/O-операція ще не буде виконана, і тут process.nextTick() допоможе нам з легкістю:

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {
  constructor() {
    super();

    process.nextTick(() => {
      this.emit('event');
    });
  }
}

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
  console.log('an event occurred!');
});

Цей приклад коду з офіційної документації, і дуже простий, але він зрозуміло і коротко показує нам яку важливу проблему ми можемо вирішити:

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {
  constructor() {
    super();
    this.emit('event');
  }
}

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
  console.log('an event occurred!');
});

Якщо виключити process.nextTick() з нашого прикладу, то подія event ніколи не спрацює, тому що виклик події відбувся ще у конструкторі класу MyEmitter, а реєстрація події — пізніше.

Онлайн-курс "Управління ІТ-командами" від Laba.
Прокачайте свої soft- і hard-скіли в управлінні кількома IT-командами, отримайте практичні стратегії та інструменти ефективного team-ліда.
Програма курсу і реєстрація

Висновок

В мене з досвіду були кандидати з інших країн, які на запитання «що таке Event Loop» відповідали так: «Навіщо ви ставите мені таке елементарне запитання, я людина з досвідом 5+ років, і клієнт за такі знання не платить, він платить за фічі».

Звичайно, всі платять за функціонал, тільки ось цікаво, скільки буде витрачено часу і яка буде якість коду, якщо ти не знаєш, як все працює та яка сила є в наших руках.

Знання таких речей як фази і робота з ними допомагає нам розуміти більш проблемні місця в коді, писати код більш осмислено та вирішувати більш нетривіальні задачі без «милиць», що впливає на надійність і впевненість в роботі нашої системи.

Дякую вам за увагу і продуктивного кодування 😉

Якщо ви знайшли помилку, будь ласка, виділіть фрагмент тексту та натисніть Ctrl+Enter.

Онлайн-курс "Проджект-менеджмент у геймдеві" від Skvot.
Новий левел для тих, хто хоче поєднати менеджерські скіли та любов до ігор.Отримай необхідний скілсет та керуй командою в ігровій індустрії.
Детальніше про курс

Цей матеріал – не редакційний, це – особиста думка його автора. Редакція може не поділяти цю думку.

Топ-5 найпопулярніших блогерів березня

PHP Developer в ScrumLaunch
Всего просмотровВсього переглядів
2434
#1
Всего просмотровВсього переглядів
2434
Founder at Shallwe, Python Software Engineer (Django/React)
Всего просмотровВсього переглядів
113
#2
Всего просмотровВсього переглядів
113
Career Consultant в GoIT
Всего просмотровВсього переглядів
95
#3
Всего просмотровВсього переглядів
95
CEO & Founder в Trustee
Всего просмотровВсього переглядів
94
#4
Всего просмотровВсього переглядів
94
Рейтинг блогерів

Найбільш обговорювані статті

Топ текстів

Ваша жалоба отправлена модератору

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: