我在循环中发出HTTP请求时遇到了一些麻烦。
让我解释一下我有什么......
我创建了一个http GET来检索一些值,然后我需要为我刚从第一个请求中获取的每个值创建另一个HTTP GET。
这两个调用都没问题,如果我切断for
周期并尝试运行整个请求链就可以完美地工作,但是自从我删除循环后只有一次。我怎样才能使它发挥作用?
以下是代码:
request({
url: "some_url",
method: "GET",
json:true,
headers:[{'content-type': 'application/json'}]
}, function (error, response, body){
if(!error & response.statusCode === 200){
for(var i=0;i<body.length;i++){
for(var j=i;j<body.length-1;j++){
//if(i === body.length-1) return;
src = body[i].name;
dest = body[j+1].name;
console.log("sorgente ",sorg);
request({
url: "https://maps.googleapis.com/maps/api/distancematrix/json?origins="+src+"&destinations="+dest,
method: "POST",
json:true,
headers:[{'content-type': 'application/json'}]
}, function (error, response, body){
if(!error & response.statusCode === 200){
console.log("TIME ",body.rows[0].elements[0].duration.text);
return;
}else{
console.log("google API failed!: ");
return;
}
});
}
}
}else{
console.log("/google_api failed!: ");
return;
}
});
我希望我对这个问题很清楚。
答案 0 :(得分:6)
这里的问题是Javascript范围和拼写错误之一。
首先,您对body[0]
和body[1]
的数组索引进行了硬编码。看起来你的意思是他们是循环变量。
其次,您的范围问题概述,简化的伪Javascript:
var requestList = [...];
for(var i = 0; i < requestList.length; i++){
var current = requestList[i];
// make a request based on current or the data
// in current.
request(..., function(result){
// do something with the current variable
current.foo = result.bar;
});
}
所有Web请求都是异步的。曾经有一种强制它们同步运行的方法,但在大多数主流浏览器中都不推荐使用它。这意味着发出了请求,并且可能会在实际代码之外获得响应,然后调用某种回调 - 在这种情况下,是匿名内部函数function(result){...}
。
这意味着for循环在发出请求时继续执行并循环,这意味着如果请求不够快,current
将更新并且请求返回时会有所不同,for循环变量也会不同。
我遇到的这类问题的解决方案是在for循环中确定内部请求的函数。
不是直接在for循环中创建新请求,而是将其移出到自己的函数中:
var requestList = [...];
for(var i = 0; i < requestList.length; i++){
var current = requestList[i];
GetMyResourceData(current);
}
function GetMyResourceData(current){
request(..., function(result){
// do something with the current variable
current.foo = result.bar;
});
}
每次调用GetMyResourceData
函数时,都会为该函数创建一个新范围,因此当您到达回调函数时,该函数中的current
变量将被保留。
那么,这就是我建议你为代码做的事情。将for循环外的第二个请求移动到其自己的范围中。
答案 1 :(得分:0)
您是否忘记使用循环变量i和j。上面的代码将继续使用body [0]作为src和body [1]的请求作为循环持续时间的dest,其中body的长度大于&gt; = 2。 尝试使用https://github.com/caolan/async#forEachOf或https://github.com/caolan/async#each在循环中调用异步函数。