Асинхронная работа с fs через then в NodeJS

С методами модуля fs асинхронно можно работать не только через коллбэки, но и через промисы. Для этого есть специальное свойство promises, содержащее в себе промисные аналоги методов для работы с файловой системой. К примеру, для метода fs.readFile его промисный аналог будет fs.promises.readFile.

Чтение файлов

Давайте выведем в консоль содержимое какого-нибудь файла:

fs.promises.readFile('readme.txt', 'utf8').then(data => { console.log(data); });

Пусть в файле записано число. Прочитайте этот файл и выведите в консоль сумму цифр этого числа.

Обработка исключений

Добавим теперь обработку исключительных ситуаций:

fs.promises.readFile('readme.txt', 'utf8').then(data => { console.log(data); }).catch(err => { console.log('ошибка'); });

Попробуйте прочитать несуществующий файл. Убедитесь, что при этом произойдет исключительная ситуация. Допишите ваш код так, чтобы он обрабатывал эту ситуацию.

Чтение и запись

Можно прочитать файл, что-то сделать с его текстом, а потом записать обратно:

fs.promises.readFile('readme.txt', 'utf8').then(data => { return fs.promises.writeFile('readme.txt', data + '!'); }).catch(err => { console.log('ошибка'); });

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

Массовая работа

Пусть у нас есть несколько файлов. Давайте прочитаем эти файлы, сольем их текст в одну строку и запишем ее в новый файл.

В отличие от коллбэков, в данном случае нам нет нужды выполнять чтение файлов по очереди. При работе с промисами мы можем записать все промисы для чтения файлов в массив, а потом воспользоваться Promise.all, чтобы осуществить запись в файл только тогда, когда все файлы будут прочитаны.

Давайте сделаем это. Пусть имена файлов у нас есть в виде массива:

let names = ['1.txt', '2.txt', '3.txt'];

Запустим цикл, в котором будем читать файлы, записывая промисы с результатами в массив:

let names = ['1.txt', '2.txt', '3.txt']; let files = []; for (let name of names) { files.push(fs.promises.readFile(name, 'utf8')); } console.log(files); // массив промисов

Имея такой массив, мы можем вызвать then только один раз, когда все промисы выполнятся:

Promise.all(files).then(data => { fs.promises.writeFile('res.txt', data.join('')); });

Добавим обработку исключительных ситуаций:

Promise.all(files).then(data => { fs.promises.writeFile('res.txt', data.join('')); }).catch(err => { console.log('что-то пошло не так'); });

Соберем весь наш код вместе:

let names = ['1.txt', '2.txt', '3.txt']; let files = []; for (let name of names) { files.push(fs.promises.readFile(name, 'utf8')); } Promise.all(files).then(data => { fs.promises.writeFile('res.txt', data.join('')); }).catch(err => { console.log('что-то пошло не так'); });

Пусть у вас есть 5 файлов с числами. Найдите сумму этих чисел и запишите в новый файл.