Как написать функцию, которая использует асинхронные функции и потоки? - PullRequest
1 голос
/ 29 января 2020

Моя первоначальная попытка использования потоков внутри асинхронной функции была такой:

const fs = require('fs');
const openpgp = require('openpgp');
const util = require('util');


const readFileAsync = util.promisify(require('fs').readFile);

const encryptFile = async (inputFile, outputFile) => {
  const readableStream = fs.createReadStream(inputFile);
  const writeStream = fs.createWriteStream(outputFile);

  const pubKey = await readFileAsync('./public.asc');
  const options = {
    message: openpgp.message.fromBinary(readableStream),
    publicKeys: (await openpgp.key.readArmored(pubKey)).keys,
    armor: false,
  };

  const ciphertext = await openpgp.encrypt(options);
  const encrypted  = ciphertext.message.packets.write();

  const stream = await openpgp.stream.webToNode(encrypted);

  return new Promise((resolve, reject) => {
    readableStream.once('error', reject) // does not call reject if inputFile doesn't exist
    stream.once('error', reject);
    writeStream.once('finish', resolve);
    writeStream.once('error', reject);
    stream.pipe(writeStream);
  });

};

Однако я обнаружил, что если бы inputFile был путем к файлу, который не существует, readableStream испустил бы ошибка, которая не была обработана readableStream.once('error', reject). Почему это так ?

Поэтому я попытался обернуть это и в Promise и обнаружил, что мне пришлось полностью удалить мой асинхронный / ожидающий синтаксис, поэтому я закончил с этим.

Кажется, это работает, но поскольку использование потоков для меня является незнакомой территорией, кто-нибудь может указать на то, что я пропустил, и если есть просто лучший способ написания кода такого типа?

const encryptFile = (inputFile, outputFile) => new Promise((resolve, reject) => {
  const readableStream = fs.createReadStream(inputFile);
  const writeStream = fs.createWriteStream(outputFile);
  readableStream.once('error', reject);
  writeStream.once('error', reject);
  writeStream.once('finish', resolve);

  readFileAsync('./public.asc')
    .then(openpgp.key.readArmored)
    .then((pubKey) => openpgp.encrypt({
        message: openpgp.message.fromBinary(readableStream),
        publicKeys: pubKey.keys,
        armor: false,
      })
    )
    .then((encrypted) => encrypted.message.packets.write())
    .then(openpgp.stream.webToNode)
    .then((cipherNodeStream) => {
      cipherNodeStream.once('error', reject);
      cipherNodeStream.pipe(writeStream)
    })
    .catch(reject);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...