Azure Blob 存储多个同时上传的进度

Posted

技术标签:

【中文标题】Azure Blob 存储多个同时上传的进度【英文标题】:Azure blob storage multiple simultaneous uploads with progress 【发布时间】:2021-03-24 21:54:10 【问题描述】:

我正在尝试将多个文件同时从 javascript 上传到 Azure BLOB 存储。我不确定它是如何处理并行性的,但我正在尝试为每个文件/上传/承诺设置单独的进度条。

现在调用进度函数但只给出“loadedBytes”我需要一种方法来知道要更新哪个进度条。有人建议 onload 给出一个标识符,它似乎没有 onload 事件。当我使用下面的代码时,索引始终是循环中的最后一个。

   try 
        console.log("Uploading files…");
        var inputElement = document.getElementById('fileSelector');

        const promises = [];
        
        for (var fileIndex = 0; fileIndex < inputElement.files.length; fileIndex++) 
            const file = inputElement.files[fileIndex];
            var thisToken = await this.Instance.invokeMethodAsync('jsGetSASToken', file.name);
            var containerURL = new azblob.ContainerURL(thisToken, azblob.StorageURL.newPipeline(new azblob.AnonymousCredential));
            const blockBlobURL = azblob.BlockBlobURL.fromContainerURL(containerURL, file.name);
            
            var blobUploadOptions = 
                blockSize: 4 * 1024 * 1024, // 4MB block size
                parallelism: 20, // 20 concurrency
                metadata:  'testindex': fileIndex.toString() ,                    
                progress: function (ev) 
                    var percentdone = ((ev.loadedBytes / file.size) * 100);

                    // Jumps around because loadedBytes is different for each upload
                    document.getElementById('percentdone-' + fileIndex).innerhtml = percentdone.toFixed(2) + "%";

                    // fileIndex is always the last item in the loop                        
                
                
            ;

            promises.push(
                azblob.uploadBrowserDataToBlockBlob(
                    azblob.Aborter.none,
                    file,
                    blockBlobURL,
                    blobUploadOptions
                )
            );
        

        await Promise.all(promises);            
        console.log('Done.');           
     catch (error) 
        console.log("File Upload Error");
        console.log(error);
    

【问题讨论】:

嗨@TimDavis,我可以知道现在怎么样了吗?如果我的回答对你有帮助,请采纳吗? 【参考方案1】:

看来这个问题是由fileIndex 引起的。我使用file.name 作为标识符,一切正常。试试下面的代码:

<html>

<body>

    <button id="select-button">Select and upload files</button>
    <input type="file" id="file-input" multiple style="display: none;" />
    <div id="showProgress"></div>


    <p><b>Status:</b></p>
    <p id="status" style="height:160px; width: 593px; overflow: scroll;" />

    
</body>
<script src="./azure-storage-blob.js" charset="utf-8"></script>
<script>

const selectButton = document.getElementById("select-button");
const fileInput = document.getElementById("file-input");
const status = document.getElementById("status");

const reportStatus = message => 
    status.innerHTML += `$message<br/>`;
    status.scrollTop = status.scrollHeight;


const accountName = "storage account";
const sasString = "sas token";
const containerName = "container";

const containerURL = new azblob.ContainerURL(
    `https://$accountName.blob.core.windows.net/$containerName?$sasString`,
    azblob.StorageURL.newPipeline(new azblob.AnonymousCredential));

const uploadFiles = async () => 
    try 
        reportStatus("Uploading files...");
        const promises = [];
        for (var fileIndex = 0; fileIndex < fileInput.files.length; fileIndex++) 
            const file = fileInput.files[fileIndex];
            const blockBlobURL = azblob.BlockBlobURL.fromContainerURL(containerURL, file.name);

            document.getElementById('showProgress').innerHTML += file.name +":<div id='progress-"+ file.name +"'></div>"
            

            var blobUploadOptions = 
                blockSize: 4 * 1024 * 1024, // 4MB block size
                parallelism: 20, // 20 concurrency
                metadata:  'testindex': fileIndex.toString() ,                    
                progress: function (ev) 
                    var percentdone = ((ev.loadedBytes / file.size) * 100);
                    var progessItem = document.getElementById('progress-' + file.name);
                    progessItem.innerHTML = percentdone.toFixed(2) + "%";                     
                
            ;
            var promise = azblob.uploadBrowserDataToBlockBlob(
                azblob.Aborter.none, file, blockBlobURL,blobUploadOptions);
            
            promise.then((result)=>
                var progessItem = document.getElementById('progress-' + file.name);
                progessItem.innerHTML += "  <a href="+result._response.request.url+">file link</a>" 
                
            );

            promises.push(promise);
        
        await Promise.all(promises);

        reportStatus("Done.");
     catch (error) 
        console.log(error)
    


selectButton.addEventListener("click", () => fileInput.click());
fileInput.addEventListener("change", uploadFiles);


</script>

</html>

结果:

更新结果:

【讨论】:

这个答案很有帮助我还没有时间尝试,但我相信它会起作用..奖金..我们可以获得已完成承诺的文件名或索引吗? @TimDavis,感谢您的回复。我已经用代码更新了我的答案,以通过 then() 函数从 Promise 中获取存储文件链接。如果我的帖子有帮助,您能接受吗?我很乐意回答您的下一个问题

以上是关于Azure Blob 存储多个同时上传的进度的主要内容,如果未能解决你的问题,请参考以下文章

如何跟踪异步文件上传到 Azure 存储的进度

将多个 Blob 上传到 Azure 存储

将 Blob 的上传大小限制到 Azure Blob 存储

通过 Azure Front Door 将文件上传到 Blob 存储

使用 azure-storage-blob 或 azure-storage 上传和删除 Azure 存储 Blob

Flutter AZURE BLOB IMAGE UPLOAD - 如何将使用移动相机拍摄的图像上传到 azure blob 存储