Циклы JS for и while с jQuery ajax блокируются в Chrome - PullRequest
0 голосов
/ 20 января 2012

У меня есть друг, который хочет постепенно перемещать данные из одной базы данных в другую и при этом отображать ошибки. Я чувствовал, что могу помочь, написав быстрый сценарий для него, и я завершил его примерно через час, и он отлично работает в Opera и Firefox (тестирование с помощью dragonfly и firebug). Когда он попробовал это сделать в Chrome, браузер блокировался до тех пор, пока не был выполнен цикл for или while, и его завершение заняло значительно больше времени. Вот мой код (без части перехвата ошибок, которая читает json):

jQuery.noConflict();
jQuery('#myForm').submit(function(form) {
    form.preventDefault();
    var increment = (jQuery("input#increment").val())*1;
    var total = jQuery("input#total").val();
    var progress = 0;
    jQuery("#progressbar").progressbar({value: 0});
    //for (progress = 0; progress < total; progress = progress + increment)
    while (progress < total)
    {
        jQuery.ajax({
            url: 'progressBarAjax.php',
            type: "POST",
            async: false,
            dataType: "json",
            data: {
                ajax: 'goAjax',
                total: total,
                increment: increment,
                progress: progress
            },
            success: function(data){
                jQuery("#progressbar").progressbar({value: data.value});
            }
        });
        progress = progress + increment;
    }
});

также, для дальнейшего использования, код для отлова ошибок был удален во время отладки и data.value = floor (($ progress / $ total) * 100). Вы также можете увидеть, где я пробовал и то, и другое, и оба прекрасно работают в Opera и Firefox, но не в Chrome.

Знать, почему это происходит, было бы неплохо знать для будущих проектов, но я также хотел бы написать это правильно. Цель состоит в том, чтобы взять 200 тыс. Вставок / обновлений и разбить их на более мелкие куски, выполнить запросы синхронно и обновить индикатор выполнения в процессе.

Ответы [ 2 ]

2 голосов
/ 20 января 2012

Ну, вы используете async:false, поэтому браузер будет блокироваться, пока выполняется запрос. Это while также может попасть в бесконечный цикл, если приращение равно 0 ..

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

var increment, total, progress;

function getProgress(){
    jQuery.ajax({
        url: 'progressBarAjax.php',
        type: "POST",
        async: true,
        dataType: "json",
        data: {
            ajax: 'goAjax',
            total: total,           // Obviously, I don't know what these
            increment: increment,   // do on your server, so I've kept
            progress: progress      // them here.
        },
        success: function(data){
            // Assuming data.value is the progress from 1-100?
            // otherwise, figure out the progress from the data response
            progress = data.value;
            jQuery("#progressbar").progressbar({value: progress});
            if(progress < 100){
                getProgress();
            }else{
                // All done
                alert('done'); 
            }  
        }
    });
}

jQuery('#myForm').submit(function(form) {
    form.preventDefault();
    // Only go if we aren't currently.
    if(progress == null || progress == 100){
        increment = (jQuery("input#increment").val())*1;
        total = jQuery("input#total").val();
        progress = 0;
        getProgress();
    }
});
0 голосов
/ 20 января 2012

Блокировка браузера - ожидаемое поведение, если вы выполняете синхронные запросы AJAX, особенно если вы выполняете несколько из них последовательно.

Из jQuery doc :

async Boolean

По умолчанию: true

По умолчанию все запросы отправляются асинхронно (то есть по умолчанию установлено значение true). Если вам нужны синхронные запросы, установите для этого параметра значение false. Междоменные запросы и dataType: запросы «jsonp» не поддерживают синхронную работу. Обратите внимание, что синхронные запросы могут временно блокировать браузер, отключая любые действия, когда запрос активен.

Возможно, что документ читается как "может", потому что поведение не согласовано во всех браузерах. Если вы хотите принудительно перерисовать страницу, вы должны периодически разрешать выполнение JavaScript. Чтобы выполнить это, вместо использования цикла while, вызовите «вложенные» setTimeout() s или используйте асинхронные запросы и вызовите следующий запрос в обратном вызове предыдущего запроса.

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