Jquery:为每次迭代设置延迟

Jquery : Set delay for each iteration

本文关键字:迭代 设置 延迟 Jquery      更新时间:2023-09-26

假设这是我想要的逻辑:

// 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立即出现。知道如何对迭代进行正确的延迟吗?

使用promise(从技术上讲,本例中为jQuery Deferred,但概念相同(来修复流,省去了很多麻烦:

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

请注意,我正在使用.always()。。。这样,即使出现错误,我们仍然会隐藏加载指示器。您可以为.fail()添加另一个处理程序来捕获错误。

更好的是,使用.show().hide(),并使用CSS动画进行任何类似的渐变样式。虽然在这种情况下不太重要,但它使这些转换在浏览器引擎中得到了极大的优化,脱离了JavaScript,同时将应用程序逻辑与样式更加分离。

解析ajax请求时,应该调用.fadeOut((,如下所示:

$(document).ready(function(){
    $('#action').click(function(e) { 
        e.preventDefault(); 
        $("#loading").fadeIn("slow");
        performRequest();
    });
    function performRequest() {
            request()
                .always(function(jqXHR){
                    console.log(jqXHR);
                    if(jqXHR.status === 500) {
                       console.log("False");
                       var t = setTimeout(function() { 
                           performRequest();    // retry after 3sec.
                           clearTimeout(t);
                       }, 3000);
                    } else { 
                       onRequestSuccess(); // success
                    }
            });
    }
    function onRequestSuccess() {
         $("#loading").fadeOut("slow");
    }
});

以下是我所说的内容。在本例中,fadeOut是在fadeIn作为回调完成后执行的。我包括了一个暂停,以表明你也可以做到这一点。

$(function() {
  $("#test").fadeIn(2000, function() {        
        setTimeout(function() { 
          $("#test").fadeOut(2000);
        }, 1000);
    });
});
<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>

如果您希望加载在每次ajax调用之前淡出,并在成功之后淡出,那么您需要在ajax成功回调中处理淡出。使用您的代码,这将在完成时淡出。

$(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调用是asynchronous,所以在执行下一行代码之前不会等待。

如果您想在完成时fadeOut,请在ajax调用的回调函数中或在该函数中运行fadeOut()

将以下内容放在您有//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动画。