Прежде всего, я должен отметить, что существуют альтернативные методы для Array#forEach
:
Array#map
, который предназначен для создания нового массива путем сопоставления исходного (того же, что и вы делаете с .forEach
) и Array#filter
(его название говорит само за себя).
Проблема в том, что у вас есть цепочка обещаний и основанная на обратном вызове модуль. Чтобы смешать их, используйте конструктор Promise
и используйте Promise.all
, чтобы объединить их в одно обещание:
fs.readdir(csvPath)
.then(files => {
// Filter out non-csv
return files.filter(file => (file !== "README.md" && file !== ".gitignore"))
})
.then(files => {
//Returning a Promise from then handler will be awaited
return Promise.all(files.map(filename => {
const loadedFile = fs.createReadStream(csvPath + filename);
return new Promise(resolve => {
var totalCases = 0;
var totalDeaths = 0;
var totalRecovered = 0;
papa.parse(loadedFile, {
header: true,
worker: true,
step: r => {
totalCases += parseIntegerValue(r.data.Confirmed);
totalDeaths += parseIntegerValue(r.data.Deaths);
totalRecovered += parseIntegerValue(r.data.Recovered);
},
complete: () => {
resolve( {
date: filename.replace(".csv", ""),
parsed: {
confirmed: totalCases,
deaths: totalDeaths,
recovered: totalRecovered
}
});
}
});
});
}));
})
.then(dailyTotals => {
console.log(dailyTotals);
});
Вы даже можете опустить первый обработчик .then
, например .filter
это синхронная операция, и делать все внутри одной .then
:
fs.readdir(csvPath)
.then(files => {
//Returning a Promise from then handler will be awaited
return Promise.all(
files
//Filter here
.filter(file => (file !== "README.md" && file !== ".gitignore"))
//And map without a second then
.map(filename => {
const loadedFile = fs.createReadStream(csvPath + filename);
return new Promise(resolve => {
var totalCases = 0;
var totalDeaths = 0;
var totalRecovered = 0;
papa.parse(loadedFile, {
header: true,
worker: true,
step: r => {
totalCases += parseIntegerValue(r.data.Confirmed);
totalDeaths += parseIntegerValue(r.data.Deaths);
totalRecovered += parseIntegerValue(r.data.Recovered);
},
complete: () => {
resolve( {
date: filename.replace(".csv", ""),
parsed: {
confirmed: totalCases,
deaths: totalDeaths,
recovered: totalRecovered
}
});
}
});
});
})
);
})
.then(dailyTotals => {
console.log(dailyTotals);
});