Я пытаюсь загрузить несколько файлов одновременно в хранилище больших двоичных объектов Azure из JavaScript. Я не уверен, как он справляется с параллелизмом, но я пытаюсь иметь отдельные индикаторы выполнения для каждого файла/загрузки/обещания.
Теперь функция прогресса вызывается, но дает только «loadedBytes». Мне нужен способ узнать, какой индикатор выполнения нужно обновить. Один человек предложил при загрузке указать идентификатор, похоже, у него нет события загрузки. Когда я использую приведенный ниже код, индекс всегда является последним в цикле.
try {
console.info("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.info('Done.');
} catch (error) {
console.info("File Upload Error");
console.info(error);
}
Кажется, эта проблема вызвана 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.info(error)
}
}
selectButton.addEventListener("click", () => fileInput.click());
fileInput.addEventListener("change", uploadFiles);
</script>
</html>
Результат:
Результат обновления:
Этот ответ полезен. У меня еще не было времени попробовать его, но я верю, что он сработает ... бонус ... можем ли мы получить имя файла или индекс выполненного обещания?
@TimDavis, спасибо за ответ. Я обновил свой ответ кодом, чтобы получить ссылку на файл хранилища из обещаний с помощью функции then(). И если мой пост полезен, не могли бы вы его принять? Буду рад ответить на ваши следующие вопросы
Привет, @TimDavis, могу я узнать, как дела? Если мой ответ полезен, не могли бы вы его принять?