#javascript #node.js
Вопрос:
У меня есть функция, которая отправит все изображения, расположенные в папке «образцы», в функцию extractImage, затем функция extractImage вызовет сторонний API для выполнения своей операции. Но когда я пытаюсь console.log(arr), кажется, что он даже не вызывался. Я думаю, что я сделал что-то не так с обработкой асинхронности, не мог бы кто-нибудь помочь мне взглянуть. У меня есть быстрое новое в JavaScript.
let arr = [];
await fs.readdir("samples", async (err, files) => {
console.log(files);
files.map(async (val) => {
console.log(val);
let tt = await extractImage(val);
return arr.push(tt);
});
});
fs.writeFileSync("final.json", "s");
console.log(arr);
console.log("tt");
Комментарии:
1. Это первое ожидание не находится внутри асинхронной функции, поэтому оно не даст желаемого результата
2. Вы неправильно использовали fs.readdir (), и это должно быть
const files = await readdir(path);
Ответ №1:
Вы неправильно использовали fs.readdir (), и так и должно быть const files = await readdir(path)
. И вы files.map(async (val) => {...})
немедленно вернете список обещаний, которые console.log(arr)
могут быть выполнены еще до того, как эти обещания будут выполнены. Код может быть похож на следующий:
let files = await fs.readdir("samples")
console.log(files);
let promises = files.map(async (val) => {
let tt = await extractImage(val);
return tt;
});
let arr = await Promise.all(promises)
console.log(arr);
console.log("tt");
fs.writeFileSync("final.json", "s");
Ответ №2:
Я мог бы рассмотреть возможность использования promisify
в этом случае, а затем возврата массива обещаний из файлов и получения ваших данных, когда все они будут решены.
const util = require('util');
const fs = require('fs');
const readdirP = util.promisify(fs.readdir);
async function main() {
try {
const files = await readdirP('samples');
const promises = files.map(file => extractImage(file));
const data = await Promise.all(promises);
} catch(error) {
console.log(error);
}
}
main();
Ответ №3:
Редактировать:
await
не может использоваться в глобальном контексте.fs.readdir
не возвращает обещания. Он основан на обратном вызове, что означает, что вы не можете его ждать. Однако существует синхронная версия метода:fs.readdirSync
.- Начиная с узла 11, вы можете сделать это:
const fs = require('fs').promises
что позволяет использовать await и .затем на fs. Для более низких версий вы можете использовать util.promisify
.
Комментарии:
1. Как я проверил, fs.readdir() не поддерживает .затем()
Ответ №4:
В этом случае может помочь использование функции, вызываемой самостоятельно:
(async function () {
let arr = [];
await fs.readdir("samples", async (err, files) => {
console.log(files);
files.map(async (val) => {
console.log(val);
let tt = await extractImage(val);
return arr.push(tt);
});
});
fs.writeFileSync("final.json", "s");
console.log(arr);
console.log("tt");
});
Комментарии:
1. Я уже тестировал это решение раньше, но, похоже, console.log(arr); не дождался завершения fs.readdir()