技术问题:jQuery中$.each()循环不等待$.Deferred()的解决方法
逐个顺序执行选中复选框的AJAX请求
最近我碰到一个需求:遍历页面上选中的复选框,为每个复选框单独发起一次AJAX请求,必须保证请求是逐个完成后再执行下一个。
最开始我用$.each()来循环处理,但很快发现$.each()根本不会等待AJAX请求完成,直接就进入下一次循环了。虽然AJAX里可以设置async:false来强制同步,但这个参数已经被弃用了,肯定不能用这种过时的方法。
之后我尝试用$.Deferred()来处理异步流程,可循环的每一次迭代还是不会等待异步操作完成,代码如下:
$.each($checkboxes, function(key, checkbox) { $def = $.Deferred(); $checkbox = $(checkbox); $.ajax({ 'url': 'ajax/myajaxcall.php', 'data': { id: $checkbox.data('id') } }).complete(function() { console.log('done'); $def.resolve('done'); }); return $def.promise(); });
最终可行的解决方案
反复重构代码都没达到预期效果,我干脆放弃了$.each(),改用递归调用函数的方式手动迭代复选框:每次AJAX请求完成后,再传入递增的索引值触发下一次请求,这样就能100%确保请求是逐个顺序执行的。实现代码如下:
var $checkboxes = $('input[name="mycheckboxes"]:checked'), checkboxKey = 0, checkboxLength = $checkboxes.length; function callAjax(key) { console.log(key); $checkbox = $($checkboxes[key]); console.log('call ajax'); console.log($checkbox); $.ajax({ 'url': 'ajax/myajaxcall.php', 'data': { 'id': $checkbox.data('id') } }).complete(function() { console.log('done'); if(key < checkboxLength - 1) { key += 1; callAjax(key); } else { console.log('complete'); } }); } if(checkboxLength > 0) { callAjax(checkboxKey); }
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

