我正在编写一些代码来解析存储在 Zip 文件夹中的所有 CSV 文件。 我正在使用JSZip。我正在循环访问dataset
的所有文件并将每个文件转换为entry
。我将结果连接在一个名为entries
的数组中。
在以下情况下,entries
数组会发生这种情况:
- 我从循环内将其记录到控制台 - 正确打印文件。
- 我从循环外的相同函数将其记录到控制台,而无需设置超时 - 打印空数组
- 我从循环 WITH setTimeout - 正确打印文件的相同功能将其记录到控制台。
现在我从这个函数返回entries
,我尝试从以下位置返回它:
-
setTimeout - 返回未定义
-
在设置超时之外 - 返回空数组
这是代码:
private async parseAllFiles (dataset: JSZip, id: string): Promise<string[]> {
let entries: string[] = [];
await dataset.forEach( async (fileName) => {
const fileContent = await dataset.file(fileName).async("text"); // async func provided by JSZip
const parsedEntries = await this.parseCsv(fileContent, courseCode); // another async function
});
console.log('Entries are: n');
console.log(entries); // Prints empty array
setTimeout( () => {
console.log("Entries are: ");
console.log(entries); // prints perfectly
return Promise.resolve(entries); // returns undefined
}, 1500);
// return Promise.resolve(entries); // returns empty array
}
我很确定entries
过早返回,但是我该如何解决这个问题,最好不使用手动设置超时?
forEach
是一个 void 返回函数,因此不可等待。
你可以做的是创建一个承诺数组:
const promises: Promise[] = [];
然后添加到forEach
中的数组中:
dataset.forEach(fileName => {
promises.push(async () => {
const fileContent = await dataset.file(fileName).async("text");
const parsedEntries = await this.parseCsv(fileContent, courseCode);
return parsedEntries;
});
});
然后等待它们全部完成:
const entries: string[] = (await Promise.all(promises)).flat();
Promise.all
返回一个新的Promise
,解析为提供的Promise
结果的数组。
可以使用Array.flat()
将这些展平为单个数组。