Attendez que AJAX se termine avant de procéder à la boucle?

Pourquoi est-ce que chaque fois que je mets un ajax dans une boucle for, il ne se synchronise pas bien?

comme par exemple, mon code est:

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 = []; } 

Pourquoi est-ce qu’il appelle selectedIds = []; d’abord avant la requête Ajax? Est-il possible de laisser les requêtes ajax se terminer avant de passer à selectedIds = []; ? Parce que cela efface le tableau juste avant qu’il ait fini de faire les choses. : /

Tout d’abord, vous devez vraiment comprendre en quoi un appel Ajax est asynchrone (c’est ce que signifie le “A” dans Ajax). Cela signifie que l’appel de $.ajax() commence uniquement l’appel ajax (la requête est $.ajax() au serveur) et que le rest de votre code continue à fonctionner. Parfois PLUS TARD, une fois que le rest de votre code a été exécuté, le gestionnaire de rappel de réussite ou d’erreur est appelé lorsque la réponse revient du serveur. Ce n’est pas une programmation séquentielle et doit être abordé différemment.

La première chose que cela signifie est que tout ce que vous voulez avoir après l’appel ajax DOIT être dans le gestionnaire de succès ou d’erreur ou appelé à partir de là. Le code situé juste après l’appel ajax sera exécuté longtemps avant la fin de l’appel.


Il existe donc différentes manières de structurer votre code pour qu’il fonctionne avec ce concept asynchrone. Si vous souhaitez uniquement un appel ajax asynchrone en vol à la fois, vous devez procéder à cette restructuration et ne pouvez pas utiliser une simple boucle for . Au lieu de cela, vous pouvez créer une variable d’index et dans la fonction d’achèvement, incrémenter l’index et lancer la prochaine itération. Voici un moyen de le coder:

 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(); }