#javascript #promise #es6-promise
Вопрос:
Я хочу прочитать три txt-файла и сложить текстовые результаты, возвращаемые из realFile(), ниже приведен мой код, используемый для обратного вызова. Как мы используем Promise и .then() для добавления всего текста?
fs.readFile('./a.txt', 'utf8', (err, data) => {
if(err) console.log(err)
fs.readFile('./b.txt', 'utf8', (err, newData) => {
if(err) console.log(err)
fs.readFile('./c.txt', 'utf8',(err, newestData) => {
if (err) console.log(err)
console.log(data newData newestData)
})
})
})
Комментарии:
1. Узел предоставляет версию
fs
модуля на основе обещаний; используйте ее вместе сPromise.all
2. Вы хотите остановиться на ошибке или продолжить?
Ответ №1:
Вы можете использовать fs.promises
API для получения обещанных методов.
Затем просто сделайте Promise.all
:
const p1 = fs.promises.readFile('./a.txt', 'utf8')
const p2 = fs.promises.readFile('./b.txt', 'utf8')
const p3 = fs.promises.readFile('./c.txt', 'utf8')
Promise.all([p1, p2, p3])
.then(([v1, v2, v3]) => console.log(v1 v2 v3))
.catch(e => console.error(e))
Вы также можете избежать повторения с массивами:
const files = ['./a.txt', './b.txt', './c.txt']
Promise.all(
files.map(file => fs.promises.readFile(file, 'utf8'))
)
.then(([v1, v2, v3]) => console.log(v1 v2 v3))
.catch(e => console.error(e))
Если вы действительно ищете что-то с несколькими .then()
буквами s, вы могли бы сделать это таким образом (хотя это не намного лучше, чем ваш первоначальный обратный вызов).:
fs.promises.readFile('./a.txt', 'utf8').then(v1 =>
fs.promises.readFile('./b.txt', 'utf8').then(v2 =>
fs.promises.readFile('./c.txt', 'utf8').then(v3 =>
console.log(v1 v2 v3)
)
)
)
.catch(e => console.error(e))
Комментарии:
1. Я хочу показать цепочку .then() для ее реализации, есть ли способ использовать три раза .then()?
2. Зачем тебе это нужно? Чего еще вы хотите достичь с помощью этого, что не работает таким образом?
3. @LeeAlex
p1.then(file1Data => p2.then(file2Data => [file1Data, file2Data])).then(arr => p3.then(file3Data => [...arr, file3Data])).then(dataArr => { ... }).catch(...)
4. @FZs Это работает, но я просто хочу посмотреть, как использовать только .than() для сравнения с помощью обратного вызова
5. @LeeAlex Я добавил решение, использующее только
.then()
s, но реальная сила обещаний заключается в их составляемости, поэтому вам следует сравнить свой код с другими решениями в моем ответе.
Ответ №2:
Проверьте фрагмент кода ниже, я добавил логику как для обещаний, так и для асинхронного/ожидания
const fs = require('fs');
const util = require("util");
const readFile = util.promisify(fs.readFile);
// return promise which can resolved later
// data is array of promise in same order of
let data = Promise.all([
readFile('file.txt', 'utf8'),
readFile('file.txt', 'utf8'),
readFile('file.txt', 'utf8')
])
data.then(([data1, data2, data3]) => {
console.log(data1, data2, data3)
}).catch(error => console.log(error))
Мы можем достичь этого с помощью async/await даже с простым синтаксисом
const fetchData = async () => {
const data1 = await readFile('file.txt', 'utf8');
const data2 = await readFile('file.txt', 'utf8');
const data3 = await readFile('file.txt', 'utf8');
console.log(data1, data2, data3);
}
fetchData();