2015-05-07 77 views
2
$xy('#simpan').click(function() { 

    $xy('input[id="cekbok[]"]:checked').each(function() { 

    var data = (this.value); 
    var div = (this.value); 
    var str = window.location.href; 
    var res = str.replace("wp-admin/options-general.php?page=katalogu-options", "/wp-content/plugins/katalog/includes/img/loading.gif"); 
    var loading = ('<img src="'+res+'">') ; 


    $xy.ajax({ 
     type : 'POST', 
     url : '../wp-content/plugins/katalogunique/proses2.php',   
     data: { 
      id : (this.value) 
     }, 

     success:function (data) { 
      $xy('#result'+div).empty(); 
      $xy('#result'+div).append(data); 
      $xy('#tz'+div).remove(); 
     }   

    }); 

    }); 
}); 

我的函數在循環中將複選框值發送到proses2.php,但是當我運行此腳本時,它將立即運行所有ajax POST調用。我想要一個接一個地運行ajax請求,或者等到完成後,我該如何解決這個問題?jQuery Ajax等待每個函數

+0

你是什麼意思由_it將運行所有ajax POST_?多解釋一點。並且,看着'$ xy('input [id =「cekbok []」]:checked')'你似乎有多個'checkbox'和相同的'ID',這是錯誤的'ID'必須是在任何給定的文件中都是唯一發布你的'HTML'。 – lshettyl

+0

如果我檢查10複選框,那麼它將運行10 Ajax後proses2.php,是複選框ID是唯一的,這個腳本已經工作,但我想讓它做1 1 ...謝謝 –

+0

理想情況下你想要達到什麼 – dreamweiver

回答

5

這裏是一個沒有遞歸,並使用一個簡單的循環方式:

$xy('#simpan').click(function() { 

    var url = '../wp-content/plugins/katalogunique/proses2.php'; 
    var d = $.Deferred().resolve(); // empty promise 
    $xy('input[id="cekbok[]"]:checked').each(function() { 
     var div = this.value; 
     d = d.then(function(data){ 
      $xy('#result'+div).empty().append(data); 
      $xy('#tz'+div).remove(); 
      return $xy.post(url, {id: div}); // this will make the next request wait 
     }); 
    }); 
    // can d.then here for knowing when all of the requests are done. 
}); 

注意:我可以「巧妙地將它」與.reduce縮短行數從6到4,但老實說,我寧願保持循環構造OP是舒適的。這是因爲承諾鏈接 - 基本上,當你從then返回一個動作時,它會等待它,然後執行你要鏈接的下一個then

讓我們examplify:

function log(msg){ // simple function to log stuff 
 
    document.body.innerHTML += msg + "<br />"; 
 
} 
 

 
var delay = function(ms){ // this is an async request, simulating your AJAX 
 
    var d = $.Deferred(); 
 
    setTimeout(d.resolve, ms); // resolving a deferred makes its then handlers execute 
 
    return d; 
 
}; 
 

 
// $.Deferred.resolve() starts a new chain so handlers execute 
 
var p = $.Deferred().resolve().then(function(){ 
 
    log("1"); 
 
    return delay(1000); // like in your code, we're waiting for it when we chain 
 
}).then(function(){ // in the above code, this is the d = d.then part, 
 
    log("2"); // this only runs when the above delay completes 
 
    return delay(1000); 
 
}); 
 

 
// and more like in the above example, we can chain it with a loop: 
 
[3,4,5,6,7,8,9,10].forEach(function(i){ 
 
    p = p.then(function(){ 
 
     log(i); 
 
     return delay(1000); 
 
    }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

注意,這樣做$xy('#result'+div)可能是一個糟糕的主意,因爲你查詢你的視圖層爲你放了什麼事 - 考慮保持有關格作一個數組,並保持引用,而不是:)

+0

諾言的大粉絲,所以非常酷。更好地解釋這一個更詳細的,因爲它會混淆除延期頑固派之外的所有人:) –

+0

我同意這是最乾淨的解決方案 –

+0

@TrueBlueAussie謝謝,我添加了一些解釋它的文字。我會添加一個簡單的例子。 –

1

你可以使用一個遞歸函數這樣做的所有電話一個接一個:

$xy('#simpan').click(function() { 
    var str = window.location.href; 
    var i=0; things = $xy('input[id="cekbok[]"]:checked'); 
    (function doOneTask(){ 
     if (i++>=things.length) return; 
     var thing = things[i]; 
     var data = thing.value; 
     var div = thing.value; 
     var res = str.replace("wp-admin/options-general.php?page=katalogu-options", "/wp-content/plugins/katalog/includes/img/loading.gif"); 
     var loading = ('<img src="'+res+'">') ; 
     $xy.ajax({ 
      type : 'POST', 
      url : '../wp-content/plugins/katalogunique/proses2.php',   
      data: { 
       id : thing.value 
      }, 
      success:function (data) { 
       $xy('#result'+div).empty(); 
       $xy('#result'+div).append(data); 
       $xy('#tz'+div).remove(); 
      }   
     }).always(doOneTask); 
    })(); 
}); 

注意:如果你想停在第一個失敗,而不是做下一個電話,我請用done替換always

+0

是不是'var data = thing.value;'?顯然這是重複的。 – lshettyl

+0

@LShetty是的,忘記了這個改變 –

+1

做得很好,但是在遞歸函數之外初始化變量,在裏面使用,味道錯了。當然,傳遞一個簡化的列表可以保證它完全獨立,沒有外部依賴或初始化? PS。你仍然在函數內部引用'this',這是不正確的。 –

0

一種方法是使用遞歸函數,每次將列表(減去第一個條目)傳遞回去。

例如調用代碼被減少到了這一點:

$xy('#simpan').click(function() { 
    LoadAjax($xy('input[id="cekbok[]"]:checked')); 

}); 

和LoadAjax是遞歸這樣的:

function LoadAjax(elements) { 
    // Exit when done 
    if (!elements.length) return; 
    var $this = elements.first(); 
    var data = ($this.value); 
    var div = ($this.value); 
    var str = window.location.href; 
    var res = str.replace("wp-admin/options-general.php?page=katalogu-options", "/wp-content/plugins/katalog/includes/img/loading.gif"); 
    var loading = ('<img src="' + res + '">'); 

    $xy.ajax({ 
     type: 'POST', 
     url: '../wp-content/plugins/katalogunique/proses2.php', 
     data: { 
      id: ($this.value) 
     }, 

     success: function (data) { 
      $xy('#result' + div).empty(); 
      $xy('#result' + div).append(data); 
      $xy('#tz' + div).remove(); 
      // Go recursive with the rest of the list 
      LoadAjax(elements.slice(1)); 
     } 

    }); 
}