Асинхронная работа с 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('что-то пошло не так');
});