使用closure
。让我告诉你一个简单的例子
// 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"];
?>
在你的情况......与闭合
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)
}
以下的部分是没有直接关系的问题包异步调用/功能而是涉及与这个答案有关的评论。
提交了关于在评论中提到jsFiddle和下面的例子是越野车,因此它并不能证明什么。
确实,这个片段,即使不使用闭包,三次产生“Hello Kitty”;实际上,如果您将console.log()
方法替换为alert()
,您会发现它会产生六次,九次甚至十二次的“Hello Kitty”。那么,到底是怎么回事?)在三次迭代循环中,如何让警报窗口弹出六次,九次或十二次?
// 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");
};
输出:
GET http://fiddle.jshell.net/_display/closure.php?data=your-data 404 (NOT FOUND)
(9) Hello Kitty
正如你可以看到,我们已经有了一个错误和九“凯蒂猫”连续输出:)我之前更改上面的函数让我们来看看两个重要事情
首先
onreadystatechange
事件商店每次readyState
属性更改时自动调用函数或引用,而status
属性保存XMLHttpRequest对象的状态。
readyState
属性的可能值
- 0:请求未初始化
- 1:服务器连接建立
- 2:请求接收
- 3:处理请求
- 4:请求完成和响应准备就绪
个status
属性可能值
二
正如我在评论中说网页,jsfiddle.net是不可靠的测试异步片段没有一些变化。换句话说,GET
方法应更改为POST
和url
属性必须改变这个链接/echo/html/
(更多选项看看jsFiddle documentation)
现在,让我们改变从上面的例子(并按照意见代码
// 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");
};
第一输出内)://六个输出
(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'
第二输出://六个输出
(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'
没有做例子(b)所做的任何改变,我们有两个不同的输出。正如你所看到的,不同的readyState属性值的输出是yield。 但i
的值保持不变。
第三输出://在取消对线在上面的例子中showned的第三输出(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
所以,在取消保持i
为参数的函数后,我们将看到该值i
已保存。但是由于有六个输出,所以这仍然不正确,我们只需要三个输出。由于我们并不需要的readyState
所有的值或XMLHttpRequest
对象的status
属性,我们将取消注释所需的第四输出的两行
第四输出://取消注释线在上面showned的4RD输出后例(b) - 最后三个输出
i=0 - readyState=4 - Hello Kitty
i=1 - readyState=4 - Hello Kitty
i=2 - readyState=4 - Hello Kitty
最后,这应该是片断的正确版本,这是我们需要的。
另一个全能的万能机制(如我之前比喻说的)将是bind()
函数,我不喜欢它,因为它比闭包慢。
你可以在浏览器网络选项卡中检查,那真的只有一个请求被发送? – harishr
@先生问题请花你的时间来审查答案,并选择正确的答案 – domokun