Azure Blob Storage统计用户文件总大小map执行后返回0如何解决
问题原因
Array.map本身不会等待传入的async回调执行完成,你在map里写的Blob属性查询都是异步任务,外层代码执行到打印值、返回响应的节点时,这些异步任务还没执行完,storageInfoTotal还停留在初始值0。你在遍历过程中看到累加值打印正常,是因为那些打印逻辑写在异步请求的回调里,会在外层响应返回之后才陆续触发。
修复方案
使用Promise.all等待所有Blob属性查询的异步任务全部执行完成后,再做结果打印和返回即可,修复后代码如下:
const connString: string = process.env.AZURE_STORAGE_CONNECTION_STRING!; const blobServiceClient = BlobServiceClient.fromConnectionString(connString); const containerClient = blobServiceClient.getContainerClient("mycontainer"); try { const userId = req.params["user_id"]; const storageInfo = await AddToHiveModel.find({ user_id: userId }); let storageInfoTotal: number = 0; console.log(storageInfo.length); if (storageInfo.length > 0) { // 等待所有异步查询任务执行完成 await Promise.all( storageInfo.map(async (element: any) => { const blobName = `uploads/${element.user_id}/${element.filename}`; try { const blobProps = await containerClient.getBlobClient(blobName).getProperties(); storageInfoTotal += Number(blobProps.contentLength); } catch (err) { // 单个Blob查询失败仅打印错误,不中断整体统计流程 console.error(`获取Blob[${blobName}]属性失败:`, err); } }) ); } console.log("用户文件总大小:", storageInfoTotal); resp.json(storageInfoTotal); } catch (err) { console.error("Caught error", err); resp.status(500).send(err); resp.end(); }
代码优化点
- 移除了重复的数据库查询逻辑,复用第一次查询到的用户文件记录,减少不必要的IO开销
- 统一使用
async/await语法代替混写的.then链式调用,代码逻辑更直观,错误捕获更清晰 - 单个Blob查询报错时不会直接中断整个统计流程,仅记录错误日志后跳过对应文件
- 确保所有异步任务执行完毕后才返回响应,避免返回初始值0的问题
内容的提问来源于stack exchange,提问作者M.G.S SUPUNTHAKA
相关产品推荐
相关产品推荐

