Node.js & file system & async await & forEach bug All In One
Node.js & file system & async await & forEach bug All In One
Async
/Await
&Top-level await
await & forEach
bug ❌
const fs = require("fs").promises;
const path = require("path");
// const items = await fs.readdir("stores");
// console.log(items);
// SyntaxError: await is only valid in async functions and the top level bodies of modules
async function main() {
// const items = await fs.readdir("stores", { withFileTypes: true });
// for (let item of items) {
// const type = item.isDirectory() ? "folder" : "file";
// console.log(`${item.name}: ${type}`);
// }
async function findFiles(folderName, arr = []) {
let result = arr ?? [];
// 'await' expressions are only allowed within async functions and at the top levels of modules.ts(1308)
const items = await fs.readdir(folderName, { withFileTypes: true });
// ❌ items.forEach 使用 async function 包裹后,导致 await 层级 bug
items.forEach(async (item) => {
if (path.extname(item.name) === ".json") {
console.log(`Found file: ${item.name} in folder: ${folderName}`);
// result.push(`${folderName}${item.name}`);
result.push(path.join(folderName, item.name));
} else {
// this is a folder, so call this method again and pass in
// the path to the folder
await findFiles(path.join(folderName, item.name), result);
}
});
return result;
}
const files = await findFiles("stores");
console.log(`✅ files =`, files);
}
main();
solution
for...of
const fs = require("fs").promises;
const path = require("path");
// const items = await fs.readdir("stores");
// console.log(items);
// SyntaxError: await is only valid in async functions and the top level bodies of modules
async function main() {
// const items = await fs.readdir("stores", { withFileTypes: true });
// for (let item of items) {
// const type = item.isDirectory() ? "folder" : "file";
// console.log(`${item.name}: ${type}`);
// }
async function findFiles(folderName, arr = []) {
let result = arr ?? [];
// 'await' expressions are only allowed within async functions and at the top levels of modules.ts(1308)
const items = await fs.readdir(folderName, { withFileTypes: true });
// ❌ items.forEach 使用 async function 包裹后,导致 await 层级 bug
// items.forEach(async (item) => {
// if (path.extname(item.name) === ".json") {
// console.log(`Found file: ${item.name} in folder: ${folderName}`);
// // result.push(`${folderName}${item.name}`);
// result.push(path.join(folderName, item.name));
// } else {
// // this is a folder, so call this method again and pass in
// // the path to the folder
// await findFiles(path.join(folderName, item.name), result);
// }
// });
// for...of ✅ 不需要使用一层 async function 包裹
for (const item of items) {
if (path.extname(item.name) === ".json") {
// console.log(`Found file: ${item.name} in folder: ${folderName}`);
// result.push(`${folderName}${item.name}`);
result.push(path.join(folderName, item.name));
} else {
// this is a folder, so call this method again and pass in
// the path to the folder
await findFiles(path.join(folderName, item.name), result);
}
}
return result;
}
const files = await findFiles("stores");
console.log(`✅ files =`, files);
}
main();
demos
https://webgeeker-nodejsfilesys-5mr88mivquv.ws-us77.gitpod.io/
https://gitlab.com/webgeeker/node.js-file-system
gitpod
vscode copy
refs
https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop
©xgqfrms 2012-2021
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/16934306.html
未经授权禁止转载,违者必究!