循环中的Http请求

时间:2016-05-24 18:30:53

标签: javascript node.js http-request

我在循环中发出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;
            }
 });

我希望我对这个问题很清楚。

2 个答案:

答案 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#forEachOfhttps://github.com/caolan/async#each在循环中调用异步函数。