承诺中的承诺是最好的解决方案吗? for循环内读取异步节点文件

Is a promise within a promise the best solution? asynchronous node file read within for loop

下面的 Node.js 函数采用:

该函数将读取数组中列出的每个 csv 文件,并使用正则表达式测试第一行中的单元格,return生成匹配文件名的新数组。

function matchReport(shop, arr) {

    return promise = new Promise(resolve => {
        var newArray = [];
        for(var j=0;j<arr.length;++j) {
            let filename = arr[j];
            csv()
            .fromFile(filename)
            .then(reportData => {
                if (reportData[0]['Work'].match(shop.productRegex)) {
                    newArray.push(filename);
                }
                if (j === arr.length) {
                    resolve(newArray);
                }
            });
        }
    }).then(matches => {
        return {
            'shop' : shop.name,
            'reports' : matches
        }
    }).catch(e => {
        console.log(e);
    });
}

很少有函数 return 具有正确的行为,即:

{ shop: 'shop1',
  reports: [ '../artist-sales-report-2020-11-12(1).csv' ] }
{ shop: 'shop2',
  reports:
   [ '../artist-sales-report-2020-12-03.csv',
     '../artist-sales-report-2020-09-01.csv' ] }

更常见的是 return 缺少报告,如下所示:

{ shop: 'shop1',
  reports: [ '../artist-sales-report-2020-11-12(1).csv' ] }
{ shop: 'shop2',
  reports: [ '../artist-sales-report-2020-12-03.csv' ] }

我知道问题出在哪里,在 csv reportData 块内。我知道这是一个异步问题,我试图编写更详细的 if..then 或 switch 语句作为 hack 解决方案,但没有成功。在这个承诺中创建更多承诺对我来说似乎有点草率和混乱,但我也没有成功。

使用 async/await 和您不喜欢的嵌套承诺,您可以将代码简化为这样的代码,它应该始终等待所有结果。我假设您的问题是 fromFile 方法,感觉它本身就是异步的,因为它使用了您没有等待的 then

async function matchReport(shop, arr) {
    
    const matches = await Promise.all(arr.map(async filename => {
       
        const reportData = await csv().fromFile( filename );

        if( reportData[0]['Work'].match(shop.productRegex) ){
        
            return filename;
            
        }
        
    }));
    
    return {
        'shop': shop.name,
        'reports': matches.filter( Boolean )
    };
    
}