Javascript 在for循环中发送post请求
我想在循环中发送post请求。 例如,如果我一行发送2个请求,那么只有最后一个请求真正进行了回调 我做错了什么Javascript 在for循环中发送post请求,javascript,angularjs,for-loop,http-post,Javascript,Angularjs,For Loop,Http Post,我想在循环中发送post请求。 例如,如果我一行发送2个请求,那么只有最后一个请求真正进行了回调 我做错了什么 this.assignAUnits = function(){ var currentIncidentId = this.incident.incidentId; for (var i=0; i< this.selectedAvailableUnits.length; i++){ var unit = this.select
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);
});
}
};
this.assignAUnits=function(){
var currentIncidentId=this.incidentId.incidentId;
对于(var i=0;i
使用一个闭包
。让我给你看一个简单的例子
// 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"];
?>
输出:
GET http://fiddle.jshell.net/_display/closure.php?data=your-data 404 (NOT FOUND)
(9) Hello Kitty
如您所见,我们有一个错误和九个“Hello Kitty”连续输出:)在我更改上述函数之前,让我们看看两件重要的事情
首先
onreadystatechange
事件存储一个函数或引用,每当readyState
属性更改时,该函数或引用将自动调用,status
属性保留XMLHttpRequest对象的状态
readyState
属性可能值
- 0:请求未初始化
- 1:已建立服务器连接
- 2:收到请求
- 3:处理请求
- 4:请求已完成,响应已准备就绪
状态
属性可能值
- 200:好的
- 404:找不到页面
GET
方法应更改为POST
,而url
属性必须更改为此链接/echo/html/
(有关更多选项,请参阅)
现在,让我们更改上面的示例(并遵循代码中的注释)
第二项产出:/六项产出
(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属性值的不同输出已被修改。
但是i
的值保持不变
第三个输出://在取消注释示例(b)中上述第三个输出的行之后
因此,在取消注释将i
作为参数保存的函数后,我们看到i
的值已保存。但这仍然是错误的,因为有六个输出,我们只需要三个。由于我们不需要XMLHttpRequest
对象的readyState
或status
属性的所有值,让我们取消注释第四个输出所需的两行
第四个输出://在取消注释示例(b)中显示的第四个输出的行之后-最后是三个输出
i=0 - readyState=4 - Hello Kitty
i=1 - readyState=4 - Hello Kitty
i=2 - readyState=4 - Hello Kitty
最后,这应该是代码段的正确版本,这就是我们需要的
另一个万能的、万能的机制(正如我之前形象地说的)是
bind()
函数,我不喜欢它,因为它比闭包慢。对不起,我不使用angularjs,但是使用jQuery甚至base XMLHttpRequest发布的这两种方法对我来说很好:
<button onclick="sendWithJQuery()">send</button>
<ul id="container"></ul>
<script src="/vendor/bower_components/jquery/dist/jquery.js"></script>
<script>
//use XMLHttpRequest
function send(){
for (var i = 1; i <= 10; i++){
var xhr = new XMLHttpRequest();
xhr.open('POST', '/test/' + i);
xhr.onreadystatechange = function(){
if (this.readyState != 4){
return;
}
var li = document.createElement('li');
li.appendChild(document.createTextNode('client time:' + new Date().toISOString() + ', data: ' + this.responseText));
container.appendChild(li);
}
xhr.send();
}
}
//use jQuery
function sendWithJQuery(){
for (var i = 1; i <= 10; i++){
$.ajax({
url: '/test/' + i,
method: "POST",
statusCode: {
200: function (data, textStatus, jqXHR) {
var li = document.createElement('li');
li.appendChild(document.createTextNode('client time:' + new Date().toISOString() + ', data: ' + JSON.stringify(data)));
container.appendChild(li);
},
500: function (data, textStatus, jqXHR) {
alert('Internal server error');
}
}
});
}
}
</script>
您试图在
for循环
中使用一个不断变化的变量url
如果在循环中不使用闭包,则只有for
的最后一个值将进入$http.post
调用。循环中的闭包可能是一个棘手的问题。查看此问题,并通过谷歌搜索了解更多理论/细节 您的代码必须按如下方式进行调整:
var doPost = function(url) {
$http.post(url).then(
function(response) {
// DOING SOMETHING
},
function(error) {
alert(error);
});
}
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
doPost(url)
}
};
var doPost=函数(url){
$http.post(url)。然后(
功能(响应){
//做某事
},
函数(错误){
警报(错误);
});
}
this.assignAUnits=函数(){
var currentIncidentId=this.incidentId.incidentId;
对于(var i=0;i
编辑:附加参考不久前,我遇到了一个非常类似的问题,您可以在这里阅读:这显然是一个结束问题。 阅读更多 还建议使用$resource而不是$http。(ng资源) 查看使用资源为循环post的示例
for(var i=0; i<$scope.ListOfRecordsToPost.length; i++){
var postSuccessCallback = function(postRec) {
console.info('Posted ' + postRec);
}($scope.ListOfRecordsToPost[i]);
lsProductionService.post({}, postSuccessCallback);
}
对于(var i=0;我可以在浏览器网络选项卡中检查,是否真的只发送了一个请求???@mr问题请花时间查看答案并选择正确的答案Hex4949,您可能是对的,但我怀疑OP是否特别受此答案启发。问题先生,问题是(我们认为)您没有告诉我们的//DOING SOMETHING
部分包含变量i
。但它位于回调函数中,直到for
循环完成后才会运行;到那时i==this.selectedAvailableUnits.length
,而不管其原始值如何。在这个闭包中有一个新变量calledi
,它实际上是与原始的i
分开的;它只在函数中声明,因此它的值不会在循环的迭代中重置。@David Knipe关闭i
并尝试连续三次回显回显“Hello Kitty”
,而不关闭:)在这种情况下,i
并不重要。仔细想想,我认为我们彼此不了解。你是说,如果函数被替换为一个普通的代码块,那么最后一个例子“Hello Kitty”
就不起作用了?我不同意。你为什么这么想?你有JSFIDLE来演示吗?@DavidKnipe好吧,这是你的r
i=0 - readyState=4 - Hello Kitty
i=1 - readyState=4 - Hello Kitty
i=2 - readyState=4 - Hello Kitty
<button onclick="sendWithJQuery()">send</button>
<ul id="container"></ul>
<script src="/vendor/bower_components/jquery/dist/jquery.js"></script>
<script>
//use XMLHttpRequest
function send(){
for (var i = 1; i <= 10; i++){
var xhr = new XMLHttpRequest();
xhr.open('POST', '/test/' + i);
xhr.onreadystatechange = function(){
if (this.readyState != 4){
return;
}
var li = document.createElement('li');
li.appendChild(document.createTextNode('client time:' + new Date().toISOString() + ', data: ' + this.responseText));
container.appendChild(li);
}
xhr.send();
}
}
//use jQuery
function sendWithJQuery(){
for (var i = 1; i <= 10; i++){
$.ajax({
url: '/test/' + i,
method: "POST",
statusCode: {
200: function (data, textStatus, jqXHR) {
var li = document.createElement('li');
li.appendChild(document.createTextNode('client time:' + new Date().toISOString() + ', data: ' + JSON.stringify(data)));
container.appendChild(li);
},
500: function (data, textStatus, jqXHR) {
alert('Internal server error');
}
}
});
}
}
</script>
router.post('/test/:i', function(req, res) {
var i = req.params.i;
var t = new Date().toISOString();
setTimeout(function(){
res.send({i: i, t: t});
}, 1000);
});
var doPost = function(url) {
$http.post(url).then(
function(response) {
// DOING SOMETHING
},
function(error) {
alert(error);
});
}
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
doPost(url)
}
};
for(var i=0; i<$scope.ListOfRecordsToPost.length; i++){
var postSuccessCallback = function(postRec) {
console.info('Posted ' + postRec);
}($scope.ListOfRecordsToPost[i]);
lsProductionService.post({}, postSuccessCallback);
}