问题
I want to iterate over a CSV file in node, and for each row, call an asynchronous function and wait for it to complete.
How can I do this?
I have:
const getFile = async function(url) {
const response = await page.goto(url, { waitUntil: 'networkidle2' });
await page.waitFor(3000);
const ad = await page.waitForSelector('div.chart');
await ad.screenshot({
path: path
});
};
fs.createReadStream(fname)
.pipe(csv())
.on('data', (row) => {
let id = row.ad_id;
let url = 'xxxx' + id;
await getFile(path);
}).on('end', () => {
console.log('CSV file successfully processed');
});
But this gives me SyntaxError: await is only valid in async function
, throwing the error on the await getFile(path);
line.
回答1:
You're getting a SyntaxError because, as it says, await
is only valid in an async
function. You can fix this by making your callback async
, but that alone won't cause the pipe to stop emitting further data
events until the async function finishes. You can probably, however, do this manually like so:
const csvPipe = fs.createReadStream(fname).pipe(csv());
csvPipe.on('data', async (row) => {
csvPipe.pause();
let id = row.ad_id;
let url = 'xxxx' + id;
await getFile(path);
csvPipe.resume();
}).on('end', () => {
console.log('CSV file successfully processed');
});
回答2:
Since the getFile
function is already a promise, you can pause and resume the pipe using the promise functions and without making the function async.
const csvPipe = fs.createReadStream(fname).pipe(csv());
csvPipe.on('data', (row) => {
csvPipe.pause();
let id = row.ad_id;
let url = 'xxxx' + id;
getFile(path).finally(() => csvPipe.resume());
}).on('end', () => {
console.log('CSV file successfully processed');
});
来源:https://stackoverflow.com/questions/59976549/iterate-over-csv-file-and-run-await-for-each-row