Skip to main content

Батьківський і дочірній процес

1. Загальний принцип

Коли ти створюєш дочірній процес, Node.js надає канали зв'язку між ним і батьком. Ці канали можна використовувати для:

  • передачі текстових даних (stdin/stdout/stderr),
  • або двостороннього обміну повідомленнями через IPC (Inter-Process Communication).

2. Варіант 1 - Через стандартні потоки (stdin / stdout / stderr)

Це класичний спосіб спілкування між програмами в UNIX.

Батько надсилає дані в child.stdin, а дочірній процес читає їх із process.stdin.

Приклад:

main.js

javascript
const { spawn } = require('child_process'); // Запускаємо дочірній процес (Node.js-скрипт) const child = spawn('node', ['child.js']); // Надсилаємо дані в stdin дочірнього процесу child.stdin.write('42\n'); child.stdin.end(); // Отримуємо відповідь із stdout child.stdout.on('data', (data) => { console.log('Відповідь від дочірнього процесу:', data.toString()); });

child.js

javascript
process.stdin.on('data', (data) => { const num = parseInt(data.toString(), 10); const result = num * 2; process.stdout.write(`Результат: ${result}\n`); });

Як це працює:

  • Батько пише дані в stdin дочірнього процесу.
  • Дочірній читає їх через process.stdin.
  • Результат повертається через stdout.

Підходить для:

  • запуску CLI-команд, утиліт, зовнішніх програм;
  • взаємодії через стандартні потоки (як у shell).

3. Варіант 2 - Через IPC (Inter-Process Communication)

Це вбудований канал зв'язку між процесами Node.js, який працює лише за створення дочірнього процесу за допомогою fork().

Дозволяє надсилати об'єкти JavaScript, а не лише текст!

Приклад:

main.js

javascript
const { fork } = require('child_process'); // Запускаємо дочірній процес Node.js const child = fork('child.js'); // Надсилаємо об'єкт child.send({ task: 'calculate', number: 10 }); // Отримуємо відповідь child.on('message', (msg) => { console.log('Відповідь від дочірнього процесу:', msg); });

child.js

javascript
process.on('message', (msg) => { if (msg.task === 'calculate') { const result = msg.number * 2; process.send({ result }); } });

Що відбувається:

  • fork() автоматично створює IPC-канал.
  • child.send() надсилає повідомлення дочірньому процесу.
  • process.on('message') у дочірньому процесі отримує його.
  • Відповідь повертається через process.send().

Підходить для:

  • обміну JSON-даними;
  • систем розподілених задач (task workers);
  • написання власних "воркерів" на Node.js.

4. Варіант 3 - Через аргументи при запуску

Іноді простіше передати дані один раз під час запуску процесу, наприклад, через аргументи командного рядка.

Приклад:

main.js

javascript
const { spawn } = require('child_process'); // Передаємо аргументи в процес const child = spawn('node', ['child.js', '15']); child.stdout.on('data', (data) => { console.log('Відповідь:', data.toString()); });

child.js

javascript
const num = parseInt(process.argv[2], 10); console.log('Подвоєне значення:', num * 2);

Тут process.argv[2] містить аргумент, переданий від батька.

Підходить для:

  • одноразової передачі параметрів;
  • скриптів і CLI-команд.

5. Варіант 4 - Через оточення (env)

Ти можеш передати дані дочірньому процесу через змінні середовища.

Приклад:

main.js

javascript
const { spawn } = require('child_process'); const child = spawn('node', ['child.js'], { env: { VALUE: 100 } });

child.js

javascript
console.log('VALUE із середовища:', process.env.VALUE);

Підходить для:

  • конфігурації, ключів, секретів;
  • сценаріїв розгортання й DevOps-задач.

6. Порівняння способів передачі даних

СпосібПередачаТип данихПідходить для
stdin / stdoutПотокиТекст / бінарні даніCLI-програми, пайплайни
child.send() / process.on('message')IPCОб'єкти JSNode.js ↔ Node.js
Аргументи командного рядкаОдноразовоРядкиПрості параметри
Змінні середовища (env)ОдноразовоРядкиКонфігурація, секрети

7. Приклад комбінованої взаємодії

main.js

javascript
const { fork } = require('child_process'); const child = fork('child.js'); // Надсилаємо дані child.send({ action: 'start', payload: [1, 2, 3] }); // Отримуємо відповіді в процесі роботи child.on('message', (msg) => { console.log('Повідомлення від дочірнього процесу:', msg); }); // Завершуємо процес setTimeout(() => child.kill(), 2000);

child.js

javascript
process.on('message', (msg) => { if (msg.action === 'start') { const result = msg.payload.map(n => n * 2); process.send({ result }); } });

Це двостороння й повністю асинхронна комунікація

  • батько й дитина можуть передавати дані одне одному, не блокуючи потік.

Підсумок

ПідхідІнструментДаніДвосторонній зв'язокОсобливості
Потоки stdin/stdoutspawn, execТекст / бінарніТакУніверсальний, але вимагає серіалізації
IPC-каналforkОб'єкти JSТакНайзручніший між Node.js-процесами
Аргументиspawn, execFileРядкиНіОдноразова передача
Оточення (env)spawn, execРядкиНіПередача конфігурації

Висновок:

Батьківський процес може надсилати дані дочірньому різними способами:

  • через stdin (для зовнішніх програм),
  • через IPC (send() / on('message')) для Node.js-процесів,
  • через аргументи чи змінні середовища для одноразових параметрів.

Найгнучкіший і найбільш "нативний" для Node.js спосіб - це IPC через fork(), тому що він дозволяє передавати об'єкти й події, а не лише текст.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.