简体   繁体   中英

How to avoid for await...of with csv-parse

I am looking to be educated on this issue as I have spent a few days trying to resolve it on my own, to no avail.

I am using csv-parse to parse a CSV file.
I am using ESLint as my Linter
I am using the Airbnb JavaScript Style Guide plugin for ESLint
I am running this on the backend using NodeJS

My function is:

const { parse } = require('csv-parse');
const fs = require('fs');
const csvFile = 'myCsvFile.csv';

async function parseCsv(csvFile) {
  const records = [];
  const parser = fs.createReadStream(csvFile).pipe(parse({ delimiter: ',', columns: true }));
  for await (const record of parser) {
    records.push(record);
  }
  return records;

The function works well, however I am trying to abide by Airbnb's Style Guide, which does not like the for await...of loop as it is hitting me with the no-restricted-syntax violation.

I am curious on if there is a better way to write this to fall in line with Airbnb's Style Guide or, if this is one of those situations where it's OK to ignore the violation?

The styleguide says:

11.2 Don't use generators for now. Why? They don't transpile well to ES5.

Fortunately if you're using a recent NodeJS version, you don't need to transpile down, and can use the engine's native support. For browsers this advice is also outdated soon.

How about using events end returning promise?

async function parseCsv(csvFile) {
  return new Promise((resolve) => {
    const records = [];
    const stream = fs.createReadStream(csvFile);
    const parser = stream.pipe(parse({ delimiter: ',', columns: true }));
    
    parser.on('readable', () => {
      while (record = parser.read()) {
        records.push(record);
      }
    });

    let ended = false;

    parser.on('error', (error) => {
      console.error(error.message);
      if (!ended) {
        ended = true;
        resolve(records);
      }
    });

    parser.on('end', () => {
      if (!ended) {
        ended = true;
        resolve(records);
      }
    });
  });
}

Based on advice given in the answers, I am going to ignore the Airbnb Style Guide and use the Async iterator method.

Final code:

const { parse } = require('csv-parse');
const fs = require('fs');
const path = require('path');
const debug = require('debug')('app:csv:service');
const chalk = require('chalk');

async function parseCsv(csvFile) {
  try {
    const records = [];
    const stream = fs.createReadStream(csvFile);
    const parser = stream.pipe(parse({ delimiter: ',', columns: true }));
    // eslint-disable-next-line no-restricted-syntax
    for await (const record of parser) {
      records.push(record);
    }
    return records;
  } catch (error) {
    debug(`${chalk.red('Failed')} to parse CSV`);
    debug(`${chalk.red('ERROR:')} ${error}`);
    throw error;
  }
}

It may be time to find a new Style Guide to follow. Thank you to num8er for the code advice (I took one of your ideas to make my code a little more readable).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM