Если вы вызываете функцию async
без await
, вы получаете обещание.
Ваш обработчик событий обрабатывает этот тип OK с then
(у него проблемы с обработкой ошибок),но ваш рекурсивный вызов scanDirectories
этого не делает.
Самый простой способ дождаться разрешения асинхронной функции - это использовать await
.
Так что это изменение делает рекурсивный вызов правильно:
return dirent.isDirectory() ? (await scanDirectories(res)) : res;
Обратите внимание на добавление await
.
Однако «Array.map» не предназначен для использования в асинхронных функциях. Он будет вызывать их синхронно и создавать массив обещаний. Не то, что вы хотите.
Кроме того, этот код неоправданно сложен, заключая обещание в обещание и используя try/catch
способом, который не будет работать:
getDirectories: async function(path) {
return new Promise(function (resolve, reject) {
try {
resolve(scanDirectories(path));
} catch {
reject('Error');
}
});
}
ПростоВызовите scanDirectories
непосредственно из вашего исходного обработчика событий и сделайте обработчик событий функцией async
, так что большая часть кода просто исчезнет.
В общем: если вам приходится иметь дело с асинхронными вещами, напишитеasync
и всегда await
в функции, которая ее вызывает, , даже если эта функция сама по себе . Вы можете писать асинхронные функции в любом месте, даже если они являются обработчиками событий или экспресс-маршрутами или в других контекстах, где обещание, к которому они разрешаются, не будет использовано.
Вот ваш исходный код, упрощенный и исправленный, но работающий в основном так жепуть:
ipcMain.on('fileTree', async (event, arg) => {
try {
event.reply('fileTree', await helperFile.scanDirectories(arg);
} catch (e) {
console.log(e);
}
});
// files.js
const { readdir } = require('fs').promises;
const resolvePath = require('path').resolve;
module.exports = {
scanDirectories: async function(path) {
const dirents = await readdir(path, { withFileTypes: true });
const files = [];
for (const dirent of dirents) {
const res = resolvePath(path, dirent.name);
if (dirent.isDirectory()) {
files = files.concat(await scanDirectories(res));
} else {
files.push(res);
}
});
return files;
}
}