如何在500ms等待AJAX​​请求后添加微调器?

时间:2017-02-07 13:44:16

标签: jquery ajax jquery-deferred

我有一个小问题,我很想用jQuery 3正确解决。所以这个想法是这样的:

  1. 执行AJAX请求
  2. 等待回应。如果500ms后没有响应,请显示spinner
  3. 当我们得到回复时隐藏微调器。
  4. 我目前有一些工作。但问题是:这是正确或首选的方式吗?

    // helper function for setTimeout
    function wait(ms) {
        var deferred = $.Deferred();
        setTimeout(function() { deferred.resolve() }, ms);
        return deferred.promise();
    }
    
    var request = $.ajax({
        dataType: "json",
        url: "/api/articles/?" + $.param(params)
    });
    
    wait(500).then(function() {
        if (request.state() === "pending") // works, but the docs says we should do this only for debugging purposes
            $(".spinner").show();
    });
    
    request.always(function() {
        $(".spinner").hide();
    );
    

    我们可以这样使用request.state()吗?这可以用更优雅的方式解决吗?

1 个答案:

答案 0 :(得分:1)

如果不同步检查承诺状态,你应该尝试做这样的事情。

需要对代码进行相当小的修改。

  • wait()而不是承诺中返回延期
  • 调用wait(500)并保留对返回的Deferred的引用。
  • 无条件地显示微调器对wait(500) Deferred。
  • 的实现
  • 拒绝wait(500)延迟解决ajax承诺,从而确保超时无法在以后解决。

这将有效地在wait(500)延迟和$.ajax()承诺之间建立竞赛,前者试图显示微调器,后者试图阻止它。

function delay(ms) {
    return jQuery.Deferred(function(dfrd) {
        setTimeout(dfrd.resolve, ms);
    });
}

var showSpinner = delay(500); // a Deferred that will be resolved after 500ms, unless rejected before that.

showSpinner.then(function() {
    $(".spinner").show();
}, function() {
    console.log('The ajax request settled before the timeout');
});

jQuery.ajax({
    dataType: 'json',
    url: '/api/articles/?' + $.param(params)
}).always(function() {
    $(".spinner").hide(); // hide spinner (if the timeout won the race)
    showSpinner.reject(); // prevent the spinner from being shown
});