2009-09-16 86 views
23

我有一個jQuery對話框打開,然後進行AJAX調用。我想這樣做是爲了讓對話框關閉或按下取消按鈕時,AJAX調用被取消,並且它的回調函數不被調用。我能想到的一些方法用一個變量來做到這一點,像這樣:在返回之前取消jQuery 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); 
     } 
    }); 
    } 

但是,不知何故,感覺髒我,它實際上並沒有從完成停止AJAX調用。有沒有內置的方法可以取消正在進行的AJAX調用?

+0

不是我試過的東西,但get()方法返回底層的XMLHttpRequest,它可以是abort()。這會有幫助嗎? – Andy 2009-09-16 18:02:43

+0

[取消之前的ajax請求jquery](http:// stackoverflow。com/questions/4342438/cancel-before-ajax-request-jquery) – Phrogz 2011-10-20 14:34:22

回答

14

好了,所以基於關閉使用由$不用彷徨函數返回的XmlHttpRequest對象的建議的,我想出了這一點:

function doStuff(){ 
    var ajaxRequest = $.ajax({ 
         url : 'url/url/url', 
         type : "GET", 
         success : function(data){ 
          ajaxRequest = null; 
          doSuccessStuff(data); 
         } 
         }); 

    $('#dialog').dialog({ 
     title: 'Stuff Dialog', 
     bgiframe: true, 
     modal: true, 
     buttons: { 
     Cancel: function() { 
      if (ajaxRequest) 
      ajaxRequest.abort(); 
      doCancelStuff(); 
     } 
     } 
    }); 
    } 

似乎工作,感覺對我更清潔。

+3

不要忘記檢查ajaxRequest爲空。你應該在'success'方法中重置它 - 然後你可以判斷是否存在活動的ajax請求 – 2010-01-21 01:46:20

+0

即使在中止請求之後,仍然可以調用doSuccessStuff()。看到我的答案下面的技術來防範這一點。 – Phrogz 2011-04-21 15:12:25

4

它似乎是這樣,但我從來沒有這樣做過。

$.get返回XmlHttpRequest對象,該對象具有可調用的abort()方法。也許試試?

5

jQuery中沒有方法,但是您可以使用從jQuery get/post/ajax函數返回的XmlHttpRequest對象。

jQuery blog

// Perform a simple Ajax request 
var req = $.ajax({ 
    type: "GET", 
    url: "/user/list/", 
    success: function(data) { 
    // Do something with the data... 
    // Then remove the request. 
    req = null; 
    } 
}); 

// Wait for 5 seconds 
setTimeout(function(){ 
    // If the request is still running, abort it. 
    if (req) req.abort(); 
}, 5000); 
17

當我有可能被解僱多次回調,但我想只能用最後一個,我用這個模式:

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討論上面的代碼。

+0

我想知道如何在Backbone的背景下做到這一點? – 2012-07-25 13:04:53

+0

頂部的代碼完全適合我 – 2013-07-19 23:26:52

0

如果你在腳本中添加一個條件,你的ajax的條件爲true,你輸出你的html,否則,你不輸出任何東西,那麼你可以做簡單的if(html)檢查成功函數像這樣:

$.ajax({ 
     type: "GET", 
     url: "url.php", 
     data: "data="+data, 
     success: function(html) 
      { 
       if(html){ 
       $("#container").empty().html(html); 
       } 
     } 
}); 
在這個例子中

,url.php可能是這個樣子:

$data = $_GET['data']; 

if($data=="whatever"){ 
    echo "<div>Hello</div>"; 
}else{} 

這爲我工作。我知道這篇文章很舊,但希望它能幫助別人。