Моя первоначальная попытка использования потоков внутри асинхронной функции была такой:
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);
});