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

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

问题描述:

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

Why is it that whenever I put an ajax inside a for loop, it doesn't synchronize well?

例如,我的代码是:

    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查询之前?
是否可以在执行 selectedIds = []; 之前让ajax查询完成?因为它在完成数据之前就清除了数组。 :/

Why is that it calls out selectedIds = []; first before the Ajax Query? Is it possible to let the ajax queries be finished before proceding to selectedIds = [];? Because it clears the array right before it's finished doing the stuffs. :/

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

First off, you really need to understand how an Ajax call is Asynchronous (that's what the "A" in Ajax stands for). That means that calling $.ajax() only starts the ajax call (it sends the request to the server) and the rest of your code happily continues running. Sometimes LATER after the rest of your code has executed, the success or error callback handler is called when the response comes back from the server. This is NOT sequential programming and must be approached differently.

这意味着,你想要在ajax调用之后发生的任何事情都必须成功或错误处理程序或从那里调用。 ajax调用之后的代码将在ajax调用完成之前很久就运行。

The #1 thing this means is that ANYTHING that you want to have happen after the ajax call MUST be in the success or error handler or called from there. Code located right after the ajax call will be run long before the ajax call completes.

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

So, there are different ways to structure your code to work with this asynchronous concept. If you only want one asynchronous ajax call in flight at a time, you have to do this restructuring and can't use a simple for loop. Instead, you can create an index variable and in the completion function, increment the index and kick off the next iteration. Here's one way to code it:

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