Какие синхронные операции знаешь в Node.js?

Ответ

В Node.js, несмотря на асинхронную природу, существует ряд синхронных API, которые блокируют Event Loop. Их использование в основном оправдано в скриптах инициализации или CLI-утилитах, но не в серверном коде, обрабатывающем запросы.

Основные синхронные операции:

  1. Файловая система (fs): Модуль fs предоставляет синхронные версии большинства методов.

    const fs = require('fs');
    const data = fs.readFileSync('./config.json', 'utf8');
    fs.writeFileSync('./output.log', data);
  2. Дочерние процессы (child_process): Для синхронного выполнения внешних команд.

    const { execSync } = require('child_process');
    const gitVersion = execSync('git --version').toString();
  3. Криптография (crypto): Некоторые хеширующие и шифрующие методы работают синхронно.

    const crypto = require('crypto');
    const hash = crypto.createHash('sha256').update('someData').digest('hex');
  4. Сжатие (zlib): Синхронные методы для deflate/gzip.

    const zlib = require('zlib');
    const compressed = zlib.gzipSync(Buffer.from('data to compress'));
  5. Встроенные операции: Некоторые операции в ядре V8, такие как JSON.parse() или crypto.randomBytes(), также являются синхронными и блокирующими.

Ключевой недостаток: Любая синхронная операция блокирует главный поток, делая приложение неотзывчивым. Например, fs.readFileSync на большом файле остановит обработку всех входящих HTTP-запросов до своего завершения.

Ответ 18+ 🔞

Да ты посмотри, какая история! В Node.js, конечно, всё круто с асинхронностью, но есть тут такие API, которые как слон в посудной лавке — всё Event Loop блокируют напрочь. Использовать их в серверном коде, который запросы обрабатывает, — это, ёпта, чистой воды самоубийство. Хотя для скриптов инициализации или CLI-утилит — ещё куда ни шло, там и посидеть можно.

Вот основные синхронные операции, которые тебя подстерегают:

  1. Файловая система (fs): Тут, бля, целый зоопарк синхронных методов на любой вкус. Хочешь прочитать файл и намертво всё остановить? Пожалуйста!

    const fs = require('fs');
    const data = fs.readFileSync('./config.json', 'utf8');
    fs.writeFileSync('./output.log', data);

    Сделал так — и сиди, жди, пока этот файл прочитается. Все остальные запросы в это время просто в ахуе висят.

  2. Дочерние процессы (child_process): Захотел команду внешнюю выполнить и чтобы весь мир подождал? Легко!

    const { execSync } = require('child_process');
    const gitVersion = execSync('git --version').toString();

    Главный поток теперь твой личный заложник, пока git --version не отрапортует.

  3. Криптография (crypto): Некоторые методы по хешированию тоже синхронные, да.

    const crypto = require('crypto');
    const hash = crypto.createHash('sha256').update('someData').digest('hex');

    Выглядит безобидно, но если данных овердохуища, то все соседи по Event Loop начнут нервно курить.

  4. Сжатие (zlib): Захомутать данные в gzip синхронно? Без проблем!

    const zlib = require('zlib');
    const compressed = zlib.gzipSync(Buffer.from('data to compress'));

    Опять же, пока жмётся, весь сервер — на паузе. Волнение ебать просто.

  5. Встроенные операции: Даже, казалось бы, безобидные вещи вроде JSON.parse() или crypto.randomBytes() — они тоже синхронные и блокирующие. Подкрадываются тихо, как хитрая жопа.

А главная-то проблема в чём? Да в том, что любая такая операция — это хуй в пальто для твоего Event Loop. Весь главный поток встаёт колом. Представь: у тебя fs.readFileSync полез в здоровенный файл, а в это время клиенты стучатся с запросами. Им всем теперь доверия ебать ноль, потому что сервер просто не отвечает, пока чтение не закончится. Полный пиздец, а не архитектура.

Так что, чувак, думай головой. В продакшене на такие фокусы лучше даже не смотреть, а то будет вам хиросима и нигерсраки с отзывчивостью.