2015-05-07 49 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)); 
     } 

    }); 
}