You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Blob下载时progress事件仅触发一次 如何获取实时下载进度

Azure Blob 下载progress事件仅触发100%完成态的修复方案

问题原因

你当前代码拿不到实时进度是几个问题叠加导致的:

  • 你用的v2版azure-storage SDK的getBlobToStream方法,默认的进度采样间隔是动态计算的,对于你这种只有4.61KB的小文件,默认采样间隔比文件总下载时长还长,只会在下载完成时触发一次progress事件
  • 你当前是先调用下载方法、拿到返回的speedSummary对象后才绑定progress监听器,存在时序差,下载启动初期触发的进度事件会因为没有挂载监听器直接丢失
  • 原有代码没补全非403错误的reject逻辑,网络异常时会出现Promise挂死的问题

修复方案

按下面核心点调整即可:

  1. 给getBlobToStream传入显式配置,把进度采样间隔设为固定小值(比如50ms),强制SDK按固定频率抛进度事件
  2. 拿到方法返回的speedSummary对象后立刻绑定progress事件,不要加额外的同步逻辑延迟绑定
  3. 补全错误分支的Promise状态流转,避免挂死

调整后的代码如下:

async function getBackupTemplate(shipKey, historyLogBlobDirectory, reportDataBlobDirectory) {
    const historyLogStreamPath = `${window.remote.app.getPath('userData')}/backupStream1.txt`;
    const reportDataStreamPath = `${window.remote.app.getPath('userData')}/backupStream2.txt`;
    const historyLog = await new Promise((resolve, reject) => {
        const stream = fs.createWriteStream(historyLogStreamPath);
        // 配置下载参数,核心是设置固定进度采样间隔
        const downloadOptions = {
            speedSummary: {
                // 每50ms触发一次进度回调,小文件可以设到20ms保证能拿到中间进度
                triggerInterval: 50
            }
        };

        // 调用下载方法,传入配置
        const historySummary = window.blobService.getBlobToStream(
            window.containerName,
            historyLogBlobDirectory,
            stream,
            downloadOptions,
            async (err, text) => {
                console.log(historyLogStreamPath)
                console.log('historySummary1', historySummary)

                if (err) {
                    if (err.statusCode === 403) {
                        azureCustomService.setRequestDateHeaderFromAzureServerTimeStamp(err.message);
                        await azureCustomService.communicateAzureWithCustomHeader('GET', window.containerName, historyLogBlobDirectory);
                        azureCustomService.streamParsingToJSON(historyLogStreamPath, (parseErr, data) => {
                            if (parseErr) return reject(parseErr);
                            resolve(JSON.parse(data));
                        });
                    } else {
                        // 补全其他错误的reject,避免Promise挂死
                        reject(err);
                    }
                } else {
                    console.log('comp history', text)
                    azureCustomService.streamParsingToJSON(historyLogStreamPath, (parseErr, data) => {
                        if (parseErr) return reject(parseErr);
                        resolve(JSON.parse(data));
                    });
                }
            }
        );

        // 立刻绑定进度事件,不要延迟
        historySummary.on('progress', function() {
            const percentComplete = historySummary.getCompletePercent(2);
            const totalSize = historySummary.getTotalSize(true);
            const downloadedSize = historySummary.getCompleteSize(true);
            // 这里可以把进度同步给UI层做实时展示
            console.log(`下载进度:${percentComplete}%`);
            console.log(`已下载:${downloadedSize} / 总大小:${totalSize}`);
        });

        console.log('historySummary2', historySummary)
    });

    // 后续reportData的下载逻辑可以复用同样的配置和事件绑定方式
    return { historyLog };
}

补充说明

  • 如果下载的文件体积极小(几KB级别),即使采样间隔设到20ms,也可能因为本地环回/内网下载速度过快只触发1-2次进度事件,属于正常现象,可以在UI层加简单的进度平滑动画优化体验
  • 如果后续升级到v12+版本的@azure/storage-blob SDK,进度获取逻辑变更为在download方法的onProgress回调中直接返回已下载字节数,不需要再依赖speedSummary对象

内容的提问来源于stack exchange,提问作者June

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 02:51:24