JavaScript - 循环时的异步事件。

时间:2015-07-29 08:39:53

标签: javascript ajax angularjs asynchronous

我在尝试循环异步事件时遇到了一个小问题。在我的情况下,我试图缩短输入的数量,以便向服务器发送5个不同的AJAX请求,其中请求的唯一区别是ID应始终为1-5。

以下是我的代码,请注意我正在使用AngularJS,所以我正在使用他们的post方法。

function loopRequest($http, destination) {
    for(var i = 1; i < 6; i++) {
        // Attempt to preserve the value of i throughout the asynchronous call
        var tmp = i; 

        $http.post("http://localhost/test.php", {slot: tmp}).success(function(data) {
            console.log("AJAX call completed for ID: " + tmp);
        });
    }
}

执行结果如下:

AJAX call completed for ID: 5
AJAX call completed for ID: 5
AJAX call completed for ID: 5
AJAX call completed for ID: 5
AJAX call completed for ID: 5

显然我可以通过AJAX调用发回标识号,但是我不想这样做,并且在继续之前宁愿理解这里的问题。我知道数组在异步函数完成之前仍在继续,但是在java中定义一个像上面所做的临时变量将保留在数组循环的其余部分的范围内并由异步调用使用。显然这在这里不起作用。

我该怎么办?我可以在这里写出5个不同的电话,但想法是消除这样做的必要性。

3 个答案:

答案 0 :(得分:4)

原因是功能范围。因为你已经将你的tmp变量包装在$ .post函数回调之外,所以它总是会引用外部函数的范围。

尝试将请求包装到另一个函数中,将tmp变量作为参数传递

myPostfunction(tmp);

所以你总是为每个请求都有一个单独的功能范围

编辑1:

例如

function loopRequest($http, destination) {
    for(var i = 1; i < 6; i++) {
        myPostfunction(i);
    }
}

function myPostfunction(tmp){
       $http.post("http://localhost/test.php", {slot: tmp}).success(function(data) {
            console.log("AJAX call completed for ID: " + tmp);
        });
}

答案 1 :(得分:3)

我最喜欢的解决方法是IIFE,因为它不会像定义函数和调用它那样改变代码“flow”

function loopRequest($http, destination) {
    for(var i = 1; i < 6; i++) {
        // Attempt to preserve the value of i throughout the asynchronous call

        (function(captured_i) {
            $http.post("http://localhost/test.php", {slot: captured_i}).success(function(data) {
                console.log("AJAX call completed for ID: " + captured_i);
            });
        }(i));
    }
}

答案 2 :(得分:0)

这样做:

function loopRequest($http, destination) {
    for(var i = 1; i < 6; i++) {
        // Attempt to preserve the value of i throughout the asynchronous call 
        doAjax(i);
    }
}

function doAjax(tmp){
       $http.post("http://localhost/test.php", {slot: tmp}).success(function(data) {
            console.log("AJAX call completed for ID: " + tmp);
        });
}

此处i的值将复制到doAjax函数。 在您的方案中,在所有函数完成之前,您的i值已增加到5。这就是tmp最后为5的原因。

如果在函数中包装ajax,则会将i值复制到该函数中。