Подход 1
async function getTypes(arr) { // Mark the function as async
return Promise.all(arr.map(async (path) => { // Promise.all will wait for all mapped calls to be resolved
try {
const stat = await fs.stat(path) // fs.stat is async
} catch(e) {
return null
}
return stat.isFile() ? 'file' : 'directory';
}));
}
Подход 2: (модификации кода ОП)
const getTypes = arr => {
const prom = arr.reduce((acc, path) => {
acc
.then(data => {
return Promise.all([fs.stat(path), Promise.resolve(data)]);
})
.then(([stat, data]) =>
stat.isFile()
? [Promise.resolve(data.push("file")), false]
: [Promise.resolve(data.push("directory")), false]
)
.catch(() => Promise.resolve([data, true])) // so the next `then` can have access to data
.then([data, failed] => failed === true ? Promise.resolve(data.push(null)) : Promsie.resolve(data)
}, Promise.resolve([]));
return prom;
};
Подход 3: (не отказоустойчив. Т.е. Promise.all не будет работать, если в любом из асин c вызовов возникнет ошибка):
function getTypes(arr) {
const deferreds = arr.map(fs.stat);
return Promise.all(deferreds).then(stats =>
stats.map(stat => (stat.isFile() ? "file" : "directory"))
);
}
Подход 4: ( Немного изменив # 3, чтобы сделать его отказоустойчивым)
const getFileType = stat => stat.isFile() ? 'file' : 'directory'
const getFileStat = path => fs.stat(path).then(getFileType).catch(() => null)
const getTypes = paths => Promise.all(paths.map(getFileStat))