如何确保函数返回之前所有行都已执行

时间:2018-11-20 12:53:46

标签: node.js asynchronous async-await

从index.js调用readCSV

const productIds = await readCSV();

在另一个文件中:

async function readCSV() {
        const filepath = path.resolve('src/input_csv.csv');
        const readstream = await fs.createReadStream(filepath);
        const stream = await readstream.pipe(parser());
        let productIds = [];
        await stream.on('data', data => {
            productIds.push(data.SourceProductId);
            console.log('SourceProductId', data.SourceProductId);
        });
        await stream.on('end', () => {
            console.log(productIds);
        });
        if (productIds.length > 0) return productIds;
        else return 'no products found';
    });
}

它给出了输出:

in main: []
SourceProductId 1000050429
SourceProductId 1132353
SourceProductId 999915195
SourceProductId 50162873
SourceProductId 1000661087
[ '1000050429', '1132353', '999915195', '50162873', '1000661087' ]

我期望函数返回一个从CSV读取的所有值的数组。但似乎在执行stream.on语句之前返回。如何确保返回前所有行均已执行。我在每句话之前都等待着,但是没有运气

1 个答案:

答案 0 :(得分:2)

stream.on不会返回承诺,因此您不能await

您可以通过从readCSV函数返回一个承诺来解决此问题:

function readCSV() {
    return new Promise(resolve => {
        const filepath = path.resolve('src/input_csv.csv');
        const readstream = fs.createReadStream(filepath);
        const stream = readstream.pipe(parser());
        let productIds = [];
        stream.on('data', data => {
            productIds.push(data.SourceProductId);
            console.log('SourceProductId', data.SourceProductId);
        });
        stream.on('end', () => {
            console.log(productIds);
            if (productIds.length > 0) resolve(productIds);
            else resolve('no products found');
        });

    });
}

您可以通过将回调函数作为参数来创建promise。该回调函数有一个参数resolve,这是异步操作完成后调用的另一个回调函数,并传递结果。

在上面的示例中,我们在文件读取流完成后使用产品ID调用此resolve回调。

由于readCSV现在返回了一个承诺,因此您可以像在代码示例中那样await进行承诺:

const productIds = await readCSV();