3

Какие есть недостатки использования синхронных методов работы с файловой системой?

Например у

fs.unlinkSync

по сравнению с

fs.unlink

Или никаких нет, скорость работы одинаковая?

nörbörnën
  • 12,192
  • 5
  • 29
  • 40
manking
  • 6,393

2 Answers2

7

Блокировка - это когда выполнение дополнительного JavaScript в процессе Node.js должно ждать завершения операции, не являющейся JavaScript. Это происходит из-за того, что цикл обработки событий не может продолжить выполнение JavaScript во время операции блокировки.

Блокирующие методы выполняются синхронно, а неблокирующие методы - асинхронно.

В качестве примера рассмотрим синхронное чтение файла:

const fs = require('fs');
const data = fs.readFileSync('/file.md'); // blocks here until file is read

А вот - эквивалентный асинхронный пример:

const fs = require('fs');
fs.readFile('/file.md', (err, data) => {
  if (err) throw err;
});

Первый пример выглядит проще, чем второй, но имеет недостаток, заключающийся в том, что вторая строка блокирует выполнение любого дополнительного JavaScript, пока весь файл не будет прочитан. Обратите внимание, что в синхронной версии, если выдается ошибка, её нужно будет перехватить, иначе процесс завершится сбоем. В асинхронной версии автору решать, следует ли выдать ошибку, как показано в примере.

Дальше читай Overview of Blocking vs Non-Blocking

nörbörnën
  • 12,192
  • 5
  • 29
  • 40
  • 1
    Впрочем нужно понимать, что бывают ситуации когда синхронные операции имеют смысл. Например чтение конфигурационного файла без данных из которого нет никакого смысла продолжать что-то делать. Или синхронная запись какого-нибудь результата в файл в самом конце работы, когда дальше всё равно больше ничего не будет. – Alexey Ten Jan 16 '19 at 20:19
2

Важно понимать, что в node.js, в отличие от того же php у вас нет никакого стороннего сервера, сервер тоже управляется node.js

Любая синхронная операция ввода-вывода просто останавливает сервер на время ожидания ответа от подсистемы ввода-вывода.
Если у вашего сервера всего один клиент - вы, вероятно, не заметите разницы, но это всё ещё не значит, что её нет.

Асинхронные операции же напротив, выполняют запрос к системе ввода-вывода и отдают управление другим процессам. Когда запрос будет выполнен, результат будет обработан функцией обратного вызова.

Проблема не в быстродействии, а в простое сервера во время блокировки для ожидания синхронного ответа.


Современные стандарты ES позволяют писать асинхронный код в «синхронном стиле», используя async/await:

const fs = require('fs');
const promisify = require('util').promisify;
(async function(){
  await promisify(fs.writeFile)('/tmp/1.txt', 'Hello, world');
  let buf = await promisify(fs.readFile)('/tmp/1.txt');
  console.log(buf.toString());
  await promisify(fs.unlink)('/tmp/1.txt');
})();
vp_arth
  • 27,179