多文件上传Backblaze:代码未等待Promise完成就执行next的问题
解决Backblaze上传完成前调用next()的问题
你的核心问题是异步操作未被正确等待,导致next()在文件上传完成前就被调用。以下是问题拆解和修复后的代码:
问题根源
- 混用
then链与async/await,两种异步处理方式嵌套导致执行顺序混乱 fs.readdir采用回调写法,内部的上传循环不会被外部的then等待- 第二个
then会直接跳过上传流程执行,此时imageIds还没收集到文件ID
修复方案
改用Promise风格的文件操作,全程用async/await确保所有异步操作完成后再执行next():
import fs from "fs/promises"; // 改用promise版fs import B2 from "backblaze-b2"; import path from "path"; import dotenv from "dotenv"; dotenv.config(); export const uploadToBackBlaze = async (req, res, next) => { console.log("I'm here uploading to Backblaze"); const b2 = new B2({ applicationKeyId: process.env.BACKBLAZE_ACCOUNT_ID, applicationKey: process.env.BACKBLAZE_MASTER_APPLICATION_ID, }); const __dirname = path.resolve(); const tempDir = path.join(__dirname, "chapterTemp"); const imageIds = []; try { // 用await替代then,等待授权完成 await b2.authorize(); const bucketId = process.env.BACKBLAZE_BUCKET_ID; // 用promise版readdir,等待文件列表读取完成 const files = await fs.readdir(tempDir); // 遍历文件,逐个等待上传完成 for (const file of files) { const filePath = path.join(tempDir, file); // 用promise版readFile替代同步读取,避免阻塞事件循环 const fileData = await fs.readFile(filePath); const uploadFileName = file; // path.join(file)没必要,直接用文件名即可 const uploadUrl = await b2.getUploadUrl(bucketId); const response = await b2.uploadFile({ uploadUrl: uploadUrl.data.uploadUrl, uploadAuthToken: uploadUrl.data.authorizationToken, filename: uploadFileName, data: fileData, // 修复mime判断:原写法逻辑错误,会一直返回"image/png" mime: filePath.match(/\.(png|jpg|jpeg|webp)$/i)?.[0].slice(1).replace('jpg', 'jpeg') || "application/octet-stream" }); console.log(response.data.fileId); imageIds.push(response.data.fileId); } // 所有上传完成后再执行后续逻辑 console.log(imageIds); req.imageIds = imageIds; next(); } catch (error) { console.error(error); return res.status(500).json({ message: error.message }); } };
额外优化点
- 替换同步的
fs.readFileSync为异步的fs.readFile,避免阻塞Node.js事件循环 - 修复了
mime字段的逻辑错误:原写法中"image/png" || "image/jpg"...会始终返回第一个值,现在根据文件后缀动态判断 - 移除不必要的
path.join(file),直接使用文件名作为上传文件名
内容的提问来源于stack exchange,提问作者Shilajit Dutta
相关产品推荐
相关产品推荐

