问题描述
我的阿波罗服务器正在使用graphql-upload软件包,其中包括对GraphQL端点的文件上传支持。但是他们只记录了有关上传单个文件的信息。但是我们需要多个文件上传支持。好吧,我将流作为数组。但是,每当我为每个流 createReadStream 并将它们通过管道传送到cloudinary上载程序var时,它只会上载最后创建的流,而不是上载每个流。
代码
// graphql reolver
const post = async (_,{ post },{ isAuthenticated,user }) => {
if (!isAuthenticated) throw new AuthenticationError("User unauthorized");
const files = await Promise.all(post.files);
let file_urls = [];
const _uploadableFiles = cloudinary.uploader.upload_stream({ folder: "post_files" },(err,result) => {
console.log("err:",err);
console.log("result:",result);
if (err) throw err;
file_urls.push({
url: result.secure_url,public_id: result.public_id,file_type: result.Metadata,});
return result;
}
);
files.forEach(async (file) => await file.createReadStream().pipe(_uploadableFiles));
.... other db related stuff
}
此后,我从上载的文件中获取Secure_URL,该文件由cloudinary upload_stream函数回调返回。但这只给了我一个流的属性,它是所有流中的最后一个。在这种情况下请帮助我。有什么方法可以传送多个流?
解决方法
不是制作一个const上传流,而是将其变成了一个工厂函数,该函数会在每次调用管道时返回一个上传流
使用array map,以便获得可以在Promise.all中使用的数组
每个文件都应一个接一个地上传到各自的上传流中,并在完成所有操作后将生成的文件url信息附加到file_urls
(在成功回调后)。Promise.all将解决,并且代码可以恢复做其他与数据库有关的事情
const post = async (_,{ post },{ isAuthenticated,user }) => {
if (!isAuthenticated) throw new AuthenticationError("User unauthorized");
const files = await Promise.all(post.files);
let file_urls = [];
function createUploader(){
return cloudinary.uploader.upload_stream({ folder: "post_files" },(err,result) => {
console.log("err:",err);
console.log("result:",result);
if (err) throw err;
file_urls.push({
url: result.secure_url,public_id: result.public_id,file_type: result.metadata,});
return result;
}
);
}
await Promise.all( files.map(async (file) => await file.createReadStream().pipe(createUploader())) ); //map instead of forEach
//.... other db related stuff
}