Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Батьківський і дочірній процес». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Чотири способи: через стандартні потоки stdin/stdout (`spawn`), через вбудований IPC-канал `fork()` (`child.send()`/`process.on('message')`), через аргументи командного рядка, або через змінні середовища. **Ключове:** найгнучкіший спосіб для Node.js ↔ Node.js - це IPC через `fork()`, бо він передає об'єкти JS, а не лише текст.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 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 | Об'єкти JS | Node.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/stdout | `spawn`, `exec` | Текст / бінарні | Так | Універсальний, але вимагає серіалізації | | IPC-канал | `fork` | Об'єкти JS | Так | Найзручніший між Node.js-процесами | | Аргументи | `spawn`, `execFile` | Рядки | Ні | Одноразова передача | | Оточення (env) | `spawn`, `exec` | Рядки | Ні | Передача конфігурації | **Висновок:** > Батьківський процес може надсилати дані дочірньому різними способами: > - через **stdin** (для зовнішніх програм), > - через **IPC** (`send()` / `on('message')`) для Node.js-процесів, > - через **аргументи** чи **змінні середовища** для одноразових параметрів. > > Найгнучкіший і найбільш "нативний" для Node.js спосіб - це **IPC через** `fork()`, > тому що він дозволяє передавати **об'єкти й події**, а не лише текст.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.