JQuery: установка задержки для каждой итерации

Предположим, что это логика, которую я хочу:

// On fail return status = 500, else success will return PDF bytestream
function request() {
  return $.ajax({
            url: url,
            async:false,
            // other properties
        });
}

$('#action').click(function(e) {  

    $("#loading").fadeIn("slow"); // display loading

    while(true) {
        if(request().status != 200) {
            delay(3000);
        } else { break; }
    }

    $("#loading").fadeOut("slow"); // hide loading
});

Для проверки задержки без итерации и запроса этот код работает хорошо:

    $(document).ready(function(){
        $('#action').click(function(e) {  
            $("#loading").fadeIn("slow");
            setTimeout(function() {
                $("#loading").fadeOut("slow");
            }, 5000);
            e.preventDefault();
        });
    });

Проблема началась, когда я помещал некоторые петли и запрашивал внутри, например:

    var isOk;
    $(document).ready(function(){
        $('#action').click(function(e) {  

            $("#loading").fadeIn("slow");

            while(true) {
                request().always(function(jqXHR){
                    console.log(jqXHR);
                    if(jqXHR.status == 500) {
                        isOk = false;
                        setTimeout(function(){console.log("False")}, 3000);
                    } else { isOk = true; }
                });

                if(isOk) {break};
            }

            $("#loading").fadeOut("slow");
            e.preventDefault();
        });
    });

Это похоже на то, что между итерацией нет задержек. Значки загрузки fadeIn и fadeOut мгновенно. Любая идея, как сделать правильную задержку для итерации?

javascript,jquery,

1

Ответов: 4


1 принят

Вы должны позвонить. $ ( документ ). ready ( function () { $ ( '#action' ). click ( function ( e ) { e . preventDefault (); $ ( "#loading" ). fadeIn ( "slow" ); executeRequest (); }); function executeRequest () { request () . always ( function ( jqXHR ) { console . log ( jqXHR ); if ( jqXHR . status === 500 ) { console . log ( «False» ); var t = setTimeout ( function () { выполнитьRequest (); // повторить попытку через 3 сек. clearTimeout ( t ); }, 3000 ); } else { onRequestSuccess (); // success } }); } function onRequestSuccess () { $ ( "#loading" ). fadeOut ( «медленный» ); } }); когда запрос ajax разрешен, например:

$('#action').click(function(e) {  
  $('#loading').fadeIn('slow'); // display loading
  $.ajax(url).always(function (e) {
    $('#loading').fadeOut('slow'); // hide loading
  });
});

3

Используйте обещания (технически, jQuery Deferred в этом примере, но ту же концепцию), чтобы исправить поток и сэкономить много головной боли:

.always()

Обратите внимание, что я использую .fail()... таким образом, даже если есть ошибка, мы все равно будем скрывать индикатор загрузки. Вы можете добавить другого обработчика для .show()обнаружения ошибок.

Еще лучше, использовать .hide()и использовать анимации CSS для любого угасающего стиля, подобного этому. Хотя в этом случае маловероятно, что делает эти переходы чрезвычайно оптимизированными в браузере, из JavaScript, и еще больше отделяет вашу логику приложения от стилизации.$(function() { $("#test").fadeIn(2000, function() { setTimeout(function() { $("#test").fadeOut(2000); }, 1000); }); });


0

Вот о чем я говорил. В этом примере fadeOut выполняется после того, как fadeIn выполняется как обратный вызов. Я включил тайм-аут, чтобы показать, что вы тоже можете это сделать.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test" style="display:none">
  TEST DIV
</div>
$(document).ready(function(){
    $('#action').click(function(e) {  

        $("#loading").fadeIn("slow");

        while(true) {
            request().always(function(jqXHR){
                console.log(jqXHR);
                if(jqXHR.status == 500) {
                  setTimeout(function(){console.log("False")}, 3000);
                } else { 
                    $("#loading").fadeOut("slow");
                    break;
                }
            });
        }            
        e.preventDefault();
    });
});

Если вы хотите, чтобы загрузка затухала перед каждым вызовом ajax и исчезала после успеха, вам нужно будет обработать выцветание в своем обратном вызове ajax. Используя ваш код, это исчезнет после завершения.

asynchronous

0

Поскольку вызов ajax asynchronous, он не дожидается до выполнения следующей строки кода.

Если вы хотите fadeOut на финише, запустите fadeOut()внутри функции обратного вызова вызова ajax или внутри этой функции .

Поставьте следующие права //other properties:

complete: function(jqXHR, textStatus) {
  $("#loading").fadeOut("slow");
}

Вы должны использовать delay(), в setTimeout()противном случае.

Задержка:

$("#loading").fadeIn(2000);
$("#loading").delay(2000).fadeOut(2000);

SetTimeout:

$("#loading").fadeIn(2000);
setTimeout(function(){
  $("#loading").fadeOut(2000);
}, 2000);

Еще одно предложение, обрабатывать ошибки в вашем вызове Ajax, а не в цикле while:

error: function(jqXHR, textStatus, errorThrown) {
  setTimeout(function() {
    request();
  }, 3000);
}

И еще, возьмите совет @Brad и используйте CSS Animations.

JavaScript, JQuery,
Похожие вопросы