Узел JS синхронного чтения однострочного текста

#javascript #node.js #typescript

#javascript #node.js #машинописный текст

Вопрос:

У меня есть следующий случай, когда у меня есть data.txt , содержащий тысячи строк.

Моя цель — прочитать каждую строку этого файла, получить некоторые данные и сохранить их в массиве. Я использую readline и fs.createReadStream .

Вот что я сделал:

 const readingText = async () => {
  const fileStream = fs.createReadStream(
    "./data.txt"
  );

  const rl = readline.createInterface({
    input: fileStream,
    crlfDelay: Infinity
  });

  let dd = [];
  rl.on("line", line => {
    dd.push(line.split(":")[1]);
  });
  rl.on("close", async line => {
    console.log(dd);
    return dd;
  });
};

const someFunc = async () => {
  try {
    const ff = await readingText();
    console.log(ff);
  } catch (err) {
    console.log(err);
    return false;
  }
};

someFunc();
  

Проблема в том, что console.log(ff) всегда будет возвращаться, undefined пока console.log(dd) правильно возвращается требуемый dd массив, почему это? и как заставить console.log(ff) ждать, пока ff переменной будет присвоено значение dd массива?

Спасибо

Комментарии:

1. выполнение на основе событий не будет указывать вашей асинхронной функции ждать и завершаться в соответствии с инструкцией return. Возможно, вы захотите обернуть это в обещание, а затем использовать someFunc с await .

2. как это сделать?

3. добавление в качестве ответа.

Ответ №1:

Выполнение на основе событий не ожидает родительскую асинхронную функцию.

Попробуйте это:

 const readingText = async () => {
  return new Promise((resolve, reject) => {
    const fileStream = fs.createReadStream(
      "./data.txt"
    );

    const rl = readline.createInterface({
      input: fileStream,
      crlfDelay: Infinity
    });

    let dd = [];
    rl.on("line", line => {
      dd.push(line.split(":")[1]);
    });
    rl.on("close", line => {
      console.log(dd);
      return resolve(dd);
    });
  });

};

const someFunc = async () => {
  try {
    const ff = await readingText();
    console.log(ff);
  } catch (err) {
    console.log(err);
    return false;
  }
};

someFunc();
  

Комментарии:

1. Также я пропустил часть отклонения. Если rl.on(‘ошибка’), вы можете отклонить обещание, чтобы получить правильный поток try / catch.

2. да, спасибо, обертывание внутри promise — отличные советы, которые я только что осознал.