承诺中的承诺是最好的解决方案吗? for循环内读取异步节点文件
Is a promise within a promise the best solution? asynchronous node file read within for loop
下面的 Node.js 函数采用:
- 一个对象,
shop
包含一个正则表达式
- 文件名数组
该函数将读取数组中列出的每个 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 )
};
}
下面的 Node.js 函数采用:
- 一个对象,
shop
包含一个正则表达式 - 文件名数组
该函数将读取数组中列出的每个 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 )
};
}