【问题标题】:How to add spinner after 500ms pending AJAX request?如何在等待 AJAX 请求 500 毫秒后添加微调器?
【发布时间】:2017-02-07 13:44:15
【问题描述】:

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

  1. 执行 AJAX 请求
  2. 等待响应。如果 500ms 后没有响应,则显示 spinner
  3. 收到回复后隐藏微调器。

我目前有一些工作。但问题是:这是正确的还是首选的方式?

// 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()吗?可以用更优雅的方式解决这个问题吗?

【问题讨论】:

  • var deferred = $.Defereed(); 应该是var deferred = $.Deferred();
  • 试试看这个,你需要的应该就在最上面api.jquery.com/Ajax_Events
  • 我建议使用带有animation-delay: 500; 的CSS 动画。在触发 AJAX 请求时应用具有动画微调器的类,在响应时从元素中删除该类。
  • 我要做的是在全局范围内保存对计时器的引用,以便我可以检查它并在适当时取消它。像var timer; /* global scope */ 然后timer = setTimeout(...);setTimeout() 调用的函数是 function showTimer() { $(".spinner").show() },当 AJAX 完成后,取消计时器:timer.clearTimeout(); 并清除加载指示器($(".spinner").hide();)。

标签: jquery ajax jquery-deferred


【解决方案1】:

你真的应该尝试在没有同步检查承诺状态的情况下做这样的事情。

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

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

这将有效地在 wait(500) deferred 和 $.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
});

【讨论】:

    猜你喜欢
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-21
    • 2020-03-10
    • 2021-08-24
    • 1970-01-01
    • 2021-04-05
    相关资源
    最近更新 更多