3

我正在使用 Microsoft Azure 存储客户端库BlobService.createBlockBlobFromBrowserFile来允许用户将文件上传到 Azure 存储容器。我想为他们提供一种取消正在进行的上传的方法,例如,以防它很大并且需要太长时间或者他们选择了错误的文件。有什么办法可以做到这一点吗?我在 API 中看不到任何明显的东西。

我的代码基于这些示例,例如

var file = document.getElementById('fileinput').files[0];

var customBlockSize = file.size > 1024 * 1024 * 32 ? 1024 * 1024 * 4 : 1024 * 512;
blobService.singleBlobPutThresholdInBytes = customBlockSize;

var finishedOrError = false;
var speedSummary = blobService.createBlockBlobFromBrowserFile('mycontainer', file.name, file, {blockSize : customBlockSize}, function(error, result, response) {
    finishedOrError = true;
    if (error) {
        // Upload blob failed
    } else {
        // Upload successfully
    }
});
refreshProgress();

从返回的SpeedSummary对象createBlockBlobFromBrowserFile是我认为this one,它没有任何可用的东西。

也在MSDN here上问过。

4

1 回答 1

3

MSDN 将我引导到讨论相同问题的这个 github 问题,并使用自定义过滤器作为解决方案。

所以这是我第一次尝试使用过滤器来取消正在进行的上传。这当然不是完美的,但似乎在我的基本测试中起作用。我很想从真正熟悉这一点的人那里得到反馈。这是取消的正确方法,即从回调中返回吗?

我没有使用任何其他过滤器对其进行测试,例如重试过滤器。它还假设您只有一次上传:它不会重置其状态或期望多次上传。

// Filter allowing us to cancel an in-progress upload by setting 'cancel' to true.
// This doesn't cancel file chunks currently being uploaded, so the upload does continue 
// for a while after this is triggered. If the last chunks have already been sent the 
// upload might actually complete (??)
// See http://azure.github.io/azure-storage-node/StorageServiceClient.html#withFilter
var cancelUploadFilter = {
    cancel: false,              // Set to true to cancel an in-progress upload

    loggingOn: true,            // Set to true to see info on console

    onCancelComplete: null,     // Set to a function you want called when a cancelled request is (probably?) complete, 
                                // i.e. when returnCounter==nextCounter. Because when you cancel an upload it can be many 
                                // seconds before the in-progress chunks complete. 

    // Internal from here down

    nextCounter: 0,             // Increments each time next() is called. a.k.a. 'SentChunks' ? 
    returnCounter: 0,           // Increments each time next()'s callback function is called. a.k.a. 'ReceivedChunks'?
    handle: function (requestOptions, next) {
        var self = this;
        if (self.cancel) {
            self.log('cancelling before chunk sent');
            return;
        }
        if (next) {
            self.nextCounter++;
            next(requestOptions, function (returnObject, finalCallback, nextPostCallback) {
                self.returnCounter++;
                if (self.cancel) {
                    self.log('cancelling after chunk received');
                    if (self.nextCounter == self.returnCounter && self.onCancelComplete) {
                        self.onCancelComplete();
                    }

                    // REALLY ??? Is this the right way to stop the upload?
                    return;

                }
                if (nextPostCallback) {
                    nextPostCallback(returnObject);
                } else if (finalCallback) {
                    finalCallback(returnObject);
                }
            });
        }
    }, 
    log: function (msg) {
        if (this.loggingOn) {
            console.log('cancelUploadFilter: ' + msg + ' nc: ' + this.nextCounter + ', rc: ' + this.returnCounter);
        }
    },
};

在创建 blob 服务时可以使用它,如下所示:

var blobService = azure.createBlobService().withFilter(cancelUploadFilter);

然后,如果您正在上传,您可以像这样取消它:

cancelUploadFilter.cancel = true;

// optional: if you want to know when all in-progress chunks have stopped: 
cancelUploadFilter.onCancelComplete = function () { console.log('Cancelling complete'); };
于 2017-12-13T23:55:18.257 回答