无法使用一个可读流写入 Node JS 中的两个不同目标

Unable to use one readable stream to write to two different targets in Node JS

我有一个客户端应用程序,用户可以在其中上传图片。我在我的 Node JS 应用程序中收到此图像作为可读数据,然后在保存之前对其进行操作,如下所示:

uploadPhoto: async (server, request) => {  

        try {         

            const randomString = `${uuidv4()}.jpg`;
            
            const stream = Fse.createWriteStream(`${rootUploadPath}/${userId}/${randomString}`);

            const resizer = Sharp()
                                .resize({
                                    width: 450
                                });

            await data.file
                    .pipe(resizer)
                    .pipe(stream);

这工作正常,并将文件写入项目本地目录。当我尝试在同一个异步函数中再次使用相同的可读数据时,问题就来了。请注意,所有这些代码都在一个 try 块中。

        const stream2 = Fse.createWriteStream(`${rootUploadPath}/${userId}/thumb_${randomString}`);

        const resizer2 = Sharp()
                            .resize({
                                width: 45
                            });

        await data.file
                .pipe(resizer2)
                .pipe(stream2);

第二个文件已写入,但我查看文件时,似乎已损坏或未成功写入数据。第一张图总是好的。

我尝试了一些方法,发现一种方法似乎有效,但我不明白为什么。我在创建第二个写入流之前添加了这段代码:

    data.file.on('end', () => {
        console.log('There will be no more data.');
    });

将第二个写入流的代码放在 on-end 回调块中没有什么区别,但是,如果我将代码放在块外,第一个写入流代码和第二个写入流之间代码,然后就可以运行了,两个文件都写成功了。

让代码保持原样感觉不对。有没有更好的方法可以写第二个缩略图图像?我尝试在第一个写入流写入数据后使用 Sharp 模块读取文件,然后创建它的较小版本,但它不起作用。该文件似乎永远无法使用。

您有 2 个备选方案,具体取决于您的软件设计方式。

如果可能,我会避免在同一“上下文”中对同一流执行两个转换操作,例如:API 端点。我宁愿将这两个不同的转换分开,这样它们就不会在同一个输入流上工作。

如果这不可能或需要太多更改,解决方案是将输入流分叉并将其通过管道传输到两个不同的可写对象中。我通常使用 Highland.js fork 来完成这些任务。

另请参阅我关于如何使用 async/await 正确处理流的评论,以检查写入操作何时完成。