Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在for循环中访问函数内的响应值_Javascript_For Loop_Settimeout - Fatal编程技术网

Javascript 如何在for循环中访问函数内的响应值

Javascript 如何在for循环中访问函数内的响应值,javascript,for-loop,settimeout,Javascript,For Loop,Settimeout,有人能帮我一下吗,我有一个for循环,里面有一个setTimout,每秒调用服务器,服务器用一个值响应,但是当我尝试访问服务器响应时,我没有定义。这是我的密码: for (let i = 0; i <= latlng.length; i++) { setTimeout(function() { GeoCoder.geocode({ 'address': latlng[i], }, function(results, status) { if (r

有人能帮我一下吗,我有一个for循环,里面有一个setTimout,每秒调用服务器,服务器用一个值响应,但是当我尝试访问服务器响应时,我没有定义。这是我的密码:

for (let i = 0; i <= latlng.length; i++) {
  setTimeout(function() {
    GeoCoder.geocode({
      'address': latlng[i],
    }, function(results, status) {
      if (results) {
        var lng = results[0].geometry.location.lng()
        var lat = results[0].geometry.location.lat()
      }
      console.log("are we getting location", lng + "" + lat)
    });
  }, i * 250);
}

for(让i=0;i我重构了您的代码,使其更具可读性,并将API调用提取到一个单独的函数中。如果您使用这个包,它应该可以工作

var GeoCoder=require(“GeoCoder”);
常量地址=[
“南路晨边”,
“海德公园购物中心”,
“穿越北纬彼得广场的车夫”,
“瓦特大街和第三街”,
];
const callApi=i=>
地理编码(地址[i],函数(错误,数据){
控制台日志(i);
if(err)console.log(err);
如果(数据){
控制台日志(数据);
}
});
for(设i=0;icallApi(i),i*250);

}
使用承诺可以让您在一系列迭代中更好地控制响应的处理

请参见下面的示例,该示例可用于复制您试图实现的目标:

function doWork(val) {
return new Promise ((resolve, reject) => {
  setTimeout(() => {
    resolve('in setTimeout:' + val);
  }, 1000);
});
}

async function newFunc(){
  let a = 5;
  const res1 = await doWork(a);
  console.log(res1);
  a = 1;
  console.log('out of setTimeout:' + a);
}

newFunc();

您需要在循环内部创建一个函数闭包,以锁定每次迭代的循环状态,否则i将为length+1,因为在调用setTimeout时循环已经完成,并给出错误

因为您使用的是setTimout,而不是在循环中创建闭包,所以可以使用传递setTimeout的本机参数。setTimout将把超过第二个参数的任何参数传递给回调函数

for (let i = 0; i <= latlng.length; i++) {
  setTimeout(function(i) { // <-- consume the i variable
    GeoCoder.geocode({
      'address': latlng[i],
    }, function(results, status) {
      if (results) {
        var lng = results[0].geometry.location.lng()
        var lat = results[0].geometry.location.lat()
      }
      console.log("are we getting location", lng + "" + lat)
    });
  }, i * 250, i); // <-- pass in i here as an argument to setTimeout
}
for(设i=0;i如果使用的是包,则回调函数的形式参数会反转

函数(结果,状态)
替换为
函数(状态,结果)
应该可以修复打字错误

目前,由于没有错误,条件分支

  if (results) { // actually testing the error argument
     // set lng and lat
  }

从声明时起,将
lng
lat
设置为
undefined

刚刚尝试过,但在尝试控制台记录结果时仍然未定义请给出
latlng
数组的示例,以及一些元素。这是示例,var latlng=['South Road Morningside'、'Hyde Park Shopping Centre'、'Coachmans Crossing Cne Peter Place'、'Watt Ave&3rd Street',]您是否正在使用此软件包:?为了让google GeoCoder正常工作,我必须传递一个值为I的address对象。当我这样做时,我无法访问GeoCoder的结果,但在网络选项卡上检查时,我可以看到结果。下面是我如何传递它的GeoCoder.geocode({'address':addresses[I]},函数(results,err){console.log(i);if(results){console.log(results);}if(err){console.log(err);}};感谢@traktor在for循环中使用
let
初始化
i
会为循环的每次迭代创建一个新的环境记录,其中
i
将被存储。
latlng[i]
在匿名计时器回调函数中,可以看到在其作用域链中设置回调的迭代的环境记录。无需通过
setTimeout
i
作为参数传递。