js 轻松将事件流转换为异步迭代器 for await 循环

33 阅读1分钟
import { parse } from "csv-parse";
const parser = parse({ delimiter: "," });

parser.on("readable", () => {
  let record;
  while ((record = parser.read()) !== null) {
    console.log(record);
  }
});
parser.on("error", (err) => console.error(err.message));
parser.on("end", () => {});

如何将上面的代码转换为 for await 循环

for await (const record of asyncIterable) {
  console.log(record);
}

方案

async function* createCsvParseStream(parser) {
  let results: any[] = [];
  let done = false;
  let resolve: (value?: any) => void;
  let reject: (value?: any) => void;
  let promise = new Promise((res, rej) => {
    resolve = res;
    reject = rej;
  });

  parser.on("readable", () => {
    let record;
    while ((record = parser.read()) !== null) {
      results.push(record);
      resolve();
      promise = new Promise((res, rej) => {
        resolve = res;
        reject = rej;
      });
    }
  });

  parser.on("error", (err) => {
    console.error(err.message);
    done = true;
    reject();
  });

  parser.on("end", () => {
    done = true;
    resolve();
  });

  while (!done) {
    await promise;
    yield* results;
    results = [];
  }
}