首页 > 解决方案 > 在没有回调的情况下使用 Node.js 流

问题描述

要将 PDF 文件从 Node.js 服务器发送到客户端,我使用以下代码:

const pdf = printer.createPdfKitDocument(docDefinition);

const chunks = [];

pdf.on("data", (chunk) => {
    chunks.push(chunk);
});

pdf.on("end", () => {
    const pdfBuffered = `data:application/pdf;base64, ${Buffer.concat(chunks).toString("base64")}`;
    res.setHeader("Content-Type", "application/pdf");
    res.setHeader("Content-Length", pdfBuffered.length);
    res.send(pdfBuffered);
});

pdf.end();

一切正常,唯一的问题是这里的流使用回调方法而不是async/ await

我找到了一个可能的解决方案

const { pipeline } = require("stream/promises");

async function run() {
    await pipeline(
        fs.createReadStream('archive.tar'),
        zlib.createGzip(),
        fs.createWriteStream('archive.tar.gz')
    );

    console.log('Pipeline succeeded.');
}

run().catch(console.error);

但我不知道如何将初始代码应用于带有stream/promises.

标签: javascriptnode.jsasync-awaitnode-streams

解决方案


如果回调打算只执行一次,则只能将回调 API 转换为async/ 。await

您在网上找到的那个有效,因为您只是在等待整个流完成,然后回调运行一次。您所拥有的是在每个传入的数据块上执行多次的回调。

您可以查看其他资源以使流更易于使用,例如RXJS或即将发布的 ECMAScript 提议,以向该语言添加可观察对象。这两者都旨在处理回调可以执行多次的情况——这是async/await不能做的事情。


推荐阅读