【发布时间】:2020-10-31 03:37:06
【问题描述】:
我有一个客户端应用程序,用户可以在其中上传图像。我在我的 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 模块读取文件,然后创建它的较小版本,但它不起作用。该文件似乎从未准备好使用。
【问题讨论】:
-
当您将可读流通过管道()到第一个可写流时,它会被消耗一次。它不能被消耗两次。此外 .pipe() 不返回承诺,使用 await 没有用。请参阅 stackoverflow.com/a/58777486/510671 了解如何在 Node.js 中将 async/await 与流一起使用。
标签: node.js fs createwritestream