在继续循环之前等待AJAX​​完成?

为什么每当我在for循环中放入ajax时,它都不能很好地同步?

例如,我的代码是:

function addToUserGroupList() { _root.qDomId('js-assignGroupArrBtn').disabled = true for (var i = 0; i < selectedIds.length; i++) { $.ajax({ type: "POST", url: 'groupManage.ashx', dataType: 'text', data: 'type=getInfo&groupId=' + selectedIds[i], success: function (result) { if (result != '') { this.groupName = result.split('&')[0]; this.groupNotes = result.split('&')[2]; userGroupList.push({ 'uid': parseInt(selectedIds[i]), 'name': this.groupName, 'adminStr': this.groupNotes }); _root.userListObj.gourpInst.gourpTB(userGroupList); } }, error: function (XMLHttpRequest, status, errorThrown) { alert('failed to add to user\'s group.'); } }); } _root.qDomId('js-assignGroupArrBtn').disabled = false; selectedIds = []; } 

为什么它会调用selectedIds = []; 首先在Ajax查询之前? 是否可以在执行selectIds selectedIds = [];之前让ajax查询完成selectedIds = []; ? 因为它在完成数据之前就清除了数组。 :/

首先,你真的需要了解Ajax调用是如何异步的(这就是Ajax中的“A”代表的)。 这意味着调用$.ajax()只会启动ajax调用(它将请求发送到服务器),其余的代码会愉快地继续运行。 有时在其余代码执行完毕后,当响应从服务器返回时,将调用成功或错误回调处理程序。 这不是顺序编程,必须采用不同的方式。

这意味着#1意味着你想要在ajax调用之后发生的任何事情必须在成功或error handling程序中或从那里调用。 ajax调用之后的代码将在ajax调用完成之前很久运行。


因此,有不同的方法来构建代码以使用此异步概念。 如果您一次只想要一次异步ajax调用,则必须进行此重组,并且不能使用简单的for循环。 相反,您可以创建索引变量,并在完成函数中,递增索引并启动下一次迭代。 这是编码它的一种方法:

 function addToUserGroupList() { _root.qDomId('js-assignGroupArrBtn').disabled = true var i = 0; function next() { if (i < selectIds.length) { $.ajax({ type: "POST", url: 'groupManage.ashx', dataType: 'text', data: 'type=getInfo&groupId=' + selectedIds[i], success: function (result) { i++; if (result != '') { this.groupName = result.split('&')[0]; this.groupNotes = result.split('&')[2]; userGroupList.push({ 'uid': parseInt(selectedIds[i]), 'name': this.groupName, 'adminStr': this.groupNotes }); _root.userListObj.gourpInst.gourpTB(userGroupList); } next(); }, error: function (XMLHttpRequest, status, errorThrown) { alert('failed to add to user\'s group.'); } }); } else { // last one done _root.qDomId('js-assignGroupArrBtn').disabled = false; selectedIds = []; } } // kick off the first one next(); }