FileReader> Ajax сработал дважды - PullRequest
       9

FileReader> Ajax сработал дважды

0 голосов
/ 04 октября 2019

Я реализую разделитель загрузки файлов, разбиваю загруженный файл на куски с помощью API-интерфейса FileReader и отправляю его в виде отдельных запросов ajax на сервер.

Каким-то образом мои части файла загружаются несколько раз с шаблоном:

1) срез 0

2) срез 0,1

3) срез 0,1,2

Для больших файлов это часто приводитсбой браузера при достижении определенного числа параллельных загрузок.

Я хочу загружать по одной части за раз, прежде чем, возможно, протестировать, если указание определенного количества параллельных частей дает какие-либо преимущества в производительности.

Код выглядит следующим образом:

function startFileUpload() {
    if (jQuery('#upload').length) {

        var reader = {};
        var file = {};
        var slice_size = 4000 * 1024;
        var size_done = 0;
        var percent_done;

        reader = new FileReader();
        file = document.querySelector('#upload').files[0];

        upload_file(0);

        function upload_file(start) {
            var next_slice = start + slice_size + 1;
            var blob = file.slice(start, next_slice);
            reader.readAsDataURL(blob);

            reader.addEventListener("loadend", function () {
                /*reader.onload = function (event) {*/
                if (event.target.readyState !== FileReader.DONE) {
                    return;
                }

                // At this point the file data is loaded to event.target.result
                jQuery.ajax({
                    url: 'https://jvdgj5oln9.execute-api.us-east-2.amazonaws.com/Prod/upload',
                    type: 'POST',
                    dataType: 'json',
                    cache: false,
crossDomain: true,
                    data: {
                        action: 'upload',
                        slice_no: (next_slice-1)/slice_size+1,
                        file_data: event.target.result,
                        file: file.name,
                        file_type: file.type
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        console.log(jqXHR, textStatus, errorThrown);
                    },
                    success: function (data) {
                        if (size_done < start + slice_size){    
                            size_done = start + slice_size;              //<!--- comment 1
                            percent_done = Math.floor((size_done / file.size) * 100);

                            if (next_slice < file.size) {
                                // Update upload progress
                                jQuery('#upload_progress').html('Uploading File - ' + percent_done + '%');

                                // More to upload, call function recursively
                                upload_file(next_slice);
                            } else {
                                // Update upload progress
                                jQuery('#upload_progress').html('Upload Complete!');
                            }
            }
                    }
                });
            });

        }
    }
}

Я проверил с помощью отладчика Chrome, что startUpload вызывается только один раз.

Я также проверил с помощью отладчика, что код на "комментарий1 "вызывается не более одного раза для каждого среза, однако я вижу, что запрос ajax запускается с 1, затем 2, а затем 3 среза параллельно на вкладке Сеть.

Я не вижу ни одного JavaScРазрывные замыкания, которые выполняются самостоятельно? Поэтому мне не ясно, какая часть запускается несколько раз.

1 Ответ

1 голос
/ 04 октября 2019

Каждый раз, когда вы звоните upload_file(), вы подключаете новый прослушиватель событий к событию reader.loadend.

Так как reader определено вне области действия upload_file(), вы получите группу прослушивателей событий для одного и того же объекта.

Либо подключите прослушиватель событий в startFileUpload()или переместите reader в область действия upload_file().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...