取消之前的ajax请求jquery

3

根据我所了解的,解决这个问题的通用方法如下:

var DataRequest = $.ajax({ /* ... */ });

然后在 beforeSend 的 ajax 事件中执行 DataRequest.abort()。然而,这会导致没有请求被发送。

我想要实现的是:中止任何声明为 DataRequest(例如)的 ajax 操作,只允许最新的请求继续进行。目前我有一个按钮,点击它会开始发起请求并添加 loading spinner。如果我多次点击它,页面上就会出现很多 loading spinner。我该如何避免这种情况?

以下是相关代码:

beforeSend: function() {
    $('<div class="grid"></div>')
        .attr('id', 'loading')
        .hide()
        .insertBefore('#output')
        .fadeIn();
},

success: function(data) {
    $('#loading').hide(function () {
        $(this).remove();
    });
}
2个回答

17

这是我在需要多个请求且仅处理最后一个时使用的模式:

var fooXHR, fooCounter=0;
$(...).bind( 'someEvent', function(){
  // Do the Right Thing to indicate that we don't care about the request anymore
  if (fooXHR) fooXHR.abort();

  var token = ++fooCounter;
  fooXHR = $.get( ..., function(data){
    // Even aborted XHR may cause the callback to be invoked
    if (token != fooCounter) return;

    // At this point we know that we're using the data from the latest request
  });
});

编辑:我已经将此功能封装成插件形式的方法,可以在此处调用:
如何取消jQuery AJAX请求?


我认为最好在中止xhr之前设置令牌 :) - Wouter C
@WouterC 你写的好像这样做为什么是可取的很明显,但对我来说并不明显。请详细说明一下:你为什么认为行动顺序应该改变? - Phrogz

1
为什么不把加载动画作为标记的一部分并隐藏它(或在页面加载时插入)。然后在 beforeSend 中编写代码来显示它,这样当按钮被多次按下时就不会插入多个动画了。
beforeSend: function () {
   $('#loading").show();
});
除非您故意想让按钮被多次按下……考虑在第一次点击后禁用按钮。这比尝试中止最后一个 ajax 请求要简单得多。

禁用按钮是简单的解决方案,但我不想强加这种限制。此外,Phrogz提到的问题是,有时即使您发出新请求,也会触发ajax回调。 - Radu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接