我正在构建一个逻辑,使用 node.js、next.js 和 multer 包将视频上传到 cloudinary。 我有一个 mongodb 文档,我想在 cloudinary 上传功能完成后存储视频的视频 url 和 publicid。 这意味着我想等待该过程完成,在创建文档之前将其作为我回复的一部分。
不幸的是,我无法让它发挥作用。视频上传需要一些时间才能完成。我想等待回复来决定发送回给客户的内容。 这是cloudinary上传功能:
export const largeFileUploader = async(props: {targetedFile: string})=>{
const {targetedFile} = props;
try {
cloudinary.uploader.upload_large(targetedFile,
{ resource_type: "video" ,
chunk_size: 6000000, folder: 'folderName', upload_preset: 'presetName' },
function(error, result) {
console.log(error, 'error')
if(error) throw 'Error encountered';
return result
});
} catch (error) {
console.log(error)
throw 'file upload error';
};
};
我编写了另一个可以在路由中调用的函数:
const imageUploadFunct = async(req: Request, res: Response, eventType: events)=>{
const files = req?.files as Express.Multer.File[];
const imageUrl: string[] = [];
const publicId: string[] = [];
if(eventType === 'video_upload_event'){
const uploadResponse = await largeFileUploader({targetedFile: file?.path}) as any;
imageUrl.push(uploadResponse?.secure_url);
publicId.push(uploadResponse?.public_id);
if(file?.path){
removeFile({filePath: file?.path});
};
return { imageUrl, publicId };
}
};
然后在我的控制器中,我有这个:
export const httpUploadVideo = async (req: Request, res: Response)=>{
try {
const response = await imageUploaderFunc(req, res, 'video_upload_event');
return res.status(200).json(response)
} catch (error) {
return res.status(500).json('Something went wrong, refresh your page or contact support');
};
};
cloudinary 上传方法需要一些时间才能完成视频上传,然后返回响应。 在此之前,我的客户已经收到了我的回复。现在,我需要将 cloudinary 响应发送给我的客户端,但在它准备好之前,我的代码已经返回并将响应发送给客户端。 如何让我的代码等到 cloudinary 返回响应后再向客户端发送响应?
我知道当 cloudinary 通过构建事件钩子之类的东西发送反馈时,我可以选择在后台明智地更新 mongoose 数据库。但我真的不想走这条路。
largeFileUploader
功能是async
,但它不await
任何东西。 其中的异步操作使用回调而不是 Promise:
cloudinary.uploader.upload_large(
targetedFile,
{ resource_type: "video", chunk_size: 6000000, folder: 'folderName', upload_preset: 'presetName' },
function(error, result) {
console.log(error, 'error')
if(error)
throw 'Error encountered';
return result
}
);
如果服务提供 awaitable API,建议改用它。如果没有,一种选择是将此回调结构包装在 Promise 中并返回该结构,以便使用代码可以
await
它。 例如:
return new Promise(function(resolve, reject) {
cloudinary.uploader.upload_large(
targetedFile,
{ resource_type: "video", chunk_size: 6000000, folder: 'folderName', upload_preset: 'presetName' },
function(error, result) {
console.log(error, 'error')
if(error)
reject('Error encountered'); // <-- reject the Promise
resolve(result); // <-- resolve the Promise
}
);
});