我有一个jQuery对话框打开然后AJAX调用。我想使它如此,如果对话框关闭或取消按钮被按下,AJAX调用被取消并且其回调函数未被调用。我可以想到一些使用如下变量的方法:
function doStuff(){ var doCallback = true; $('#dialog').dialog({ title: 'Dialog Title',modal: true,buttons: { Cancel: function() { doCallback = false; doSomethingElse(); } } }); $.get('url/url/url',function(data){ if(doCallback){ doTheSuccessThing(data); } }); }
解决方法
当我有一个可能被触发多次的回调,但是我只想使用最后一个,我使用这种模式:
var resultsXHR,resultsTimer,resultsId=0; $('input').keyup(function(){ clearTimeout(resultsTimer); // Remove any queued request if (resultsXHR) resultsXHR.abort(); // Cancel request in progress resultsTimer = setTimeout(function(){ // Record the queued request var id = ++resultsId; // Record the calling order resultsXHR = $.get('/results',function(data){ // Capture request in progress resultsXHR = null; // This request is done if (id!=resultsId) return; // A later request is pending // ... actually do stuff here ... }); },500); // Wait 500ms after keyup });
只有abort()不足以阻止成功回调被调用;即使您尝试取消请求,您仍然可能会发现您的回调运行。这就是为什么有必要使用resultsId跟踪器并让回调停止处理,如果另一个,稍后重叠的回调已经准备好了。
鉴于这是多么普遍和麻烦,我认为以一种可重用的方式来组织它是一个好主意,它不需要你为每个你想要处理的一个独特的三元组的局部变量名:
(function($){ $.fn.bindDelayedGet = function(event,delay,url,dataCallback,dataType,callback){ var xhr,timer,ct=0; return this.bind(event,function(){ clearTimeout(timer); if (xhr) xhr.abort(); timer = setTimeout(function(){ var id = ++ct; xhr = $.get(url,dataCallback && dataCallback(),function(data){ xhr = null; if (id==ct) callback(data); },dataType); },delay); }); }; })(jQuery); // In action var inp = $('#myinput').bindDelayedGet('keyup',400,'/search',function(){ return {term:inp.val()}; },'html',function(html){ $('#searchResults').clear().append(html); } );
你可以在上面的代码中找到更详细的on my website。