循环内的 Http 请求

Http request inside a loop

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

我希望我问清楚了。

你是不是忘了使用循环变量 i 和 j。上面的代码将在循环期间继续以 body[0] 作为 src 和 body[1] 作为 dest 发出请求,前提是 body 的长度 >= 2。 尝试使用 https://github.com/caolan/async#forEachOf or https://github.com/caolan/async#each 在循环中调用异步函数。

此处的问题是 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;
    });
}

所有网络请求都是异步的。曾经有一种方法可以强制它们同步 运行,但在大多数主流浏览器中已被弃用。这意味着请求已发出,并且可能会得到响应,在您的实际代码之外,然后调用某种回调——在这种情况下,匿名内部函数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 循环之外的第二个请求移到它自己的范围内。