发送POST请求的for循环 [英] Sending post request in for loop

查看:375
本文介绍了发送POST请求的for循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在循环发送POST请求。
如果我例如发送连续2请求只有最后一个请求着实让回调。

我是什么做错了?

  this.assignAUnits =功能(){
        VAR currentIncidentId = this.incident.incidentId;
        对于(VAR I = 0; I< this.selectedAvailableUnits.length;我++){
            VAR单位= this.selectedAvailableUnits [I]
            VAR unitId = unit.unitId;            VAR URL ='/事件/'+ currentIncidentId +'/ assignUnit /+ unitId            $ http.post(URL)。然后(功能(响应){
               做什么            },功能(错误){
                警报(错误);
            });
        }
    };


解决方案

使用关闭。让我告诉你一个简单的例子

  //上的JavaScript客户端
在window.onload =函数(){
    变种F =(函数(){
        对于(I = 0; I&下; 3;我++){
            (函数(ⅰ){
                VAR XHR =新XMLHtt prequest();
                VAR URL =?closure.php数据=+ I;
                xhr.open(GET,网址,真实);
                xhr.onreadystatechange =功能(){
                    如果(xhr.readyState == 4和&放大器; xhr.status == 200){
                        的console.log(xhr.responseText); // 0,1,2
                    }
                };
                xhr.send();
            })(一世);
        }
    })();
};//服务器端(PHP在这种情况下)
< PHP
    回声$ _GET [数据];
?>

在你的情况......包住异步调用/函数封闭

 为(VAR I = 0; I< this.selectedAvailableUnits.length;我++){    (函数(一){//< ---抓        VAR单位= this.selectedAvailableUnits [I]
        VAR unitId = unit.unitId;
        VAR URL ='/事件/'+ currentIncidentId +'/ assignUnit /+ unitId
        $ http.post(URL)。然后(功能(响应){
            //做什么
        },功能(错误){
            警报(错误);
        });    })(一世); //< ----(可能是如果不需要它省略了变量i)}


<强>的部分的下方不直接相关的问题,而是与此相关的答案的评论。


提交了一份关于在评论中提到的jsfiddle 以及下面的例子是越野车,因此它不T证明什么。

这是真的,这个片段中,即使不使用闭合,产生凯蒂猫三次;实际上,如果更换的console.log()方法与一个警报()一个你会看到它产生凯蒂猫六,九,甚至十二倍。那么,是什么到底是怎么回事之一;?!),它是如何可能得到警报窗口的三个迭代循环内弹出六,九或十二倍

  //你的榜样(一)//我的意见
//
变种F =(函数(){
    对于(I = 0; I&下; 3;我++){
        //(函数(){//这样你不能有多个范围
            VAR XHR =新XMLHtt prequest();
            VAR URL =closure.php数据=你的数据? //使用/回声/ HTML /上jsfiddle.net测试
            xhr.open(GET,网址,真实); //对jsfiddle.net使用POST进行测试
            xhr.onreadystatechange =功能(){//这样你可能赶上所有readyStage属性值
                回电话(); //这样的回调函数会被调用多次
            };
            xhr.send();
        //})();
    }
})();VAR回调函数=(){
    的console.log(凯蒂猫); //或使用的警报(凯蒂猫);
};

输出:

  GET http://fiddle.jshell.net/_display/closure.php?data=your-data 404(NOT FOUND)
(9)凯蒂猫

正如你可以看到,我们已经有了一个错误九凯蒂猫连续输出:)之前,我改变功能上面让我们看看两个重要的事情

第一

的onreadystatechange 事件存储函数或引用自动每次的readyState 属性的变化,而<$称为C $ C>状态属性保存的是XMLHtt prequest对象的状态。

的readyState 属性可能值


  • 0:请求未初始化

  • 1:服务器连接建立

  • 2:收到请求

  • 3:处理请求

  • 4:请求完成和响应准备

状态属性可能值


  • 200:确定

  • 404:找不到页面

正如我在评论中说,jsfiddle.net是不可靠的检验异步片段没有一些变化。换句话说, GET 办法应改为 POST 网​​址属性必须改变这个链接 /回声/ HTML / (更多选项看看的的jsfiddle文档

现在,让我们改变从上面的例子(并按照code中的注释)

  //修正例子(二)
//
变种F =(函数(){
    对于(I = 0; I&下; 3;我++){
        //(功能(我){//取消注释此行的第3个输出
            VAR XHR =新XMLHtt prequest();
            VAR URL =/回声/ HTML;
            VAR数据=数据;
            xhr.open(POST,网址,真实);
            xhr.onreadystatechange =功能(){
                //如果(xhr.readyState == 4安培;&安培; xhr.status == 200){//取消注释该行第四届输出
                    回调(ⅰ,xhr.readyState); //取消注释该行第四届输出
                //}
            };
            xhr.send(数据);
        //})(一世); //取消注释这行第3个输出
    }
})();变种回调=函数(I,S){
    的console.log(I =+ I + - 的readyState =+ S + - 凯蒂猫);
};

1输出://六个输出

 (4)I = 3  - 的readyState = 1  - 凯蒂猫// 4项涉及readyState值为输出'服务器连接建立'
    I = 3 - '收到的请求凯蒂猫//相关readyState值为 - 的readyState = 2
    I = 3 - 的readyState = 4 - 凯蒂猫//相关readyState值为请求完成和响应准备就绪

第2个输出://六个输出

 (2)I = 3  - 的readyState = 1  - 凯蒂猫//两个相关于readyState值为输出'服务器连接建立'
    I = 3 - '收到的请求凯蒂猫//相关readyState值为 - 的readyState = 2
(3)I = 3 - 的readyState = 4 - 凯蒂猫//三个相关于readyState值为输出的要求完成和响应准备就绪

无例子(二)所做的任何更改,我们有两个不同的输出。正如你所看到的,对于不同的readyState属性值不同的输出一直是产量。
i的值保持不变。

3个输出://取消注释线在上面的例子中showned第3个输出后(B)

  I = 0  - 的readyState = 2  - 凯蒂猫//相关readyState值为收到请求
I = 0 - 的readyState = 4 - 凯蒂猫//相关readyState值为请求完成和响应准备就绪
I = 1 - 的readyState = 2 - 凯蒂猫// ...
I = 1 - 的readyState = 4 - 凯蒂猫// ...
I = 2 - 的readyState = 2 - 凯蒂猫
I = 2 - 的readyState = 4 - 凯蒂猫

因此​​,在取消其持有的功能之后 I 作为一个参数,我们可以看到, i的值有被保存。但是,这仍然不正确,因为有六个输出,我们只有三个需要。由于我们不需要的readyState 状态的属性 XMLHtt $的所有值p $ pquest 对象,我们需要注释的第四输出两行

第四输出://取消注释线在上面的例子中showned的4RD输出后(B) - 最后三路输出

  I = 0  - 的readyState = 4  - 凯蒂猫
I = 1 - 的readyState = 4 - 凯蒂猫
I = 2 - 的readyState = 4 - 凯蒂猫

最后,这应该是片段的正确版本,这就是我们需要的。

另外一个全能的,万能的机制(如我比喻之前说的)会是绑定()函数,我不知道preFER,因为它不是一个封闭慢

I would like to send post requests in loop. If i send for example 2 requests in a row only the last request really made the callback.

What am i do wrong?

this.assignAUnits = function(){
        var currentIncidentId = this.incident.incidentId;
        for (var i=0; i< this.selectedAvailableUnits.length; i++){
            var unit = this.selectedAvailableUnits[i];
            var unitId = unit.unitId;

            var url = '/incident/' + currentIncidentId + '/assignUnit/' + unitId

            $http.post(url).then(function(response) {
               DOING SOMETHING

            }, function(error) {
                alert(error);
            });          
        }
    };

解决方案

Use a closure. Let me show you a simple example

// JavaScript on Client-Side
window.onload = function() {
    var f = (function() {
        for (i = 0; i < 3; i++) {
            (function(i){
                var xhr = new XMLHttpRequest();
                var url = "closure.php?data=" + i;
                xhr.open("GET", url, true);
                xhr.onreadystatechange = function () {
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        console.log(xhr.responseText); // 0, 1, 2 
                    }
                };
                xhr.send();
            })(i);
        }
    })();
};

// Server-Side (PHP in this case)
<?php 
    echo $_GET["data"];
?>

In your case... wrap the asynchronous call/function with a closure

for (var i=0; i< this.selectedAvailableUnits.length; i++) {

    (function(i) {    // <--- the catch

        var unit = this.selectedAvailableUnits[i];
        var unitId = unit.unitId;
        var url = '/incident/' + currentIncidentId + '/assignUnit/' + unitId
        $http.post(url).then(function(response) {
            // DOING SOMETHING
        }, function(error) {
            alert(error);
        });

    })(i);    // <---- (the i variable might be omitted if it's not needed)

}


The section below is not directly related to the question but rather to the comments related to this answer.


The example submitted on jsFiddle mentioned in the comments and shown below is buggy and as such it doesn't prove anything.

It's true that this snippet, even not using a closure, yields 'Hello Kitty' three times; actually, if you replace console.log() method with the an alert() one you will see that it yields 'Hello Kitty' six, nine or even twelve times. So, what the hell is going one ;) how it's possible to get the alert window popping up six, nine or twelve times within a loop of three iterations?!

// your example (a)                                   // my comments 
//
var f = (function() {
    for (i = 0; i < 3; i++) {
        //(function(){                                // this way you can't have multiple scopes 
            var xhr = new XMLHttpRequest();
            var url = "closure.php?data=your-data";   // use /echo/html/ for testing on jsfiddle.net
            xhr.open("GET", url, true);               // use POST for testing on jsfiddle.net 
            xhr.onreadystatechange = function () {    // this way you might catch all readyStage property values
                callback();                           // this way the callback function will be called several times
            };
            xhr.send();
        //})();
    }
})();

var callback = function() {
    console.log("Hello Kitty"); // or use alert("Hello Kitty");
};

Output:

GET http://fiddle.jshell.net/_display/closure.php?data=your-data 404 (NOT FOUND) 
(9) Hello Kitty

As you could see, we've got an error and nine 'Hello Kitty' outputs in a row :) Before I change the function above let's see two important thing

First

onreadystatechange event stores a function or a reference to be called automatically each time the readyState property changes while status property holds the status of the XMLHttpRequest object.

readyState property possible values

  • 0: request not initialized
  • 1: server connection established
  • 2: request received
  • 3: processing request
  • 4: request finished and response is ready

status property possible values

  • 200: OK
  • 404: Page not found

Second

As I said in the comments, jsfiddle.net isn't reliable for testing asynchronous snippets without some changes. In other words the GET method should be changed to POST and the url property must be changed to this link /echo/html/ (for more options take a look at jsFiddle documentation)

Now, let's change the example from the above (and follow the comments within the code)

// corrected example (b)
//
var f = (function() {
    for (i = 0; i < 3; i++) {
        //(function(i){                                              // uncomment this line for the 3rd output                               
            var xhr = new XMLHttpRequest();
            var url = "/echo/html";
            var data = "data";
            xhr.open("POST", url, true);
            xhr.onreadystatechange = function () {
                //if (xhr.readyState == 4 && xhr.status == 200) {    // uncomment this line for the 4th output
                    callback(i, xhr.readyState);                     // uncomment this line for the 4th output
                //}
            };
            xhr.send(data);
        //})(i);                                                     // uncomment this line for the 3rd output
    }
})();

var callback = function(i, s) {
    console.log("i=" + i + " - readyState=" + s + " - Hello Kitty");
};

1st output: // six outputs

(4) i=3 - readyState=1 - Hello Kitty    // four outputs related to readyState value 'server connection established'
    i=3 - readyState=2 - Hello Kitty    // related to readyState value 'request received'
    i=3 - readyState=4 - Hello Kitty    // related to readyState value 'request finished and response is ready'

2nd output: // six outputs

(2) i=3 - readyState=1 - Hello Kitty    // two outputs related to readyState value 'server connection established'
    i=3 - readyState=2 - Hello Kitty    // related to readyState value 'request received'
(3) i=3 - readyState=4 - Hello Kitty    // three outputs related to readyState value 'request finished and response is ready'

Without any changes made in example (b), we've got two different outputs. As you can see, different outputs for different readyState property values has been yield. But the value of i remained the same.

3rd output: // after uncommenting the lines for the 3rd output showned above in the example (b)

i=0 - readyState=2 - Hello Kitty        // related to readyState value 'request received'
i=0 - readyState=4 - Hello Kitty        // related to readyState value 'request finished and response is ready'
i=1 - readyState=2 - Hello Kitty        // ...
i=1 - readyState=4 - Hello Kitty        // ... 
i=2 - readyState=2 - Hello Kitty
i=2 - readyState=4 - Hello Kitty

So, after uncommenting the function which holds i as an argument, we see that the value of i has been saved. But this is still incorrect since there are six outputs and we need only three. As we don't need all the values of readyState or status property of the XMLHttpRequest object, let's uncomment the two lines needed for the fourth output

4th output: // after uncommenting the lines for the 4rd output showned above in the example (b) - finally three outputs

i=0 - readyState=4 - Hello Kitty
i=1 - readyState=4 - Hello Kitty
i=2 - readyState=4 - Hello Kitty 

Finally, this should be the correct version of the snippet and this is what we need.

Another almighty, omnipotent mechanism (as I figuratively said before) would be the bind() function which I don't prefer since it's slower than a closure.

这篇关于发送POST请求的for循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆