Javascript中的变量可见性

时间:2012-05-20 12:18:45

标签: javascript google-maps

这是我的示例代码

var selected_path = [];

            for (var i = 0; i <path.length-1; i++) {
                    var request = {
                    origin: path[i],
                    destination: path[i+1],
                    travelMode: google.maps.DirectionsTravelMode.WALKING

                }

                directionsService.route(request, function(results, status) {
                    if (status == google.maps.DirectionsStatus.OK) {
                        selected_path = selected_path.concat(results.routes[0].overview_path);

                    }
                })

            }
            console.log(selected_path);  // slected_path in console is []
            poly.setPath(selected_path);
            poly.setMap(map);

在这种情况下,console中的selected_pa​​th是[]。当我在console.log(selected_pa​​th)之前添加alert(i)行时。这是添加后的代码:

var selected_path = [];

            for (var i = 0; i <path.length-1; i++) {
                    var request = {
                    origin: path[i],
                    destination: path[i+1],
                    travelMode: google.maps.DirectionsTravelMode.WALKING

                }

                directionsService.route(request, function(results, status) {
                    if (status == google.maps.DirectionsStatus.OK) {
                        selected_path = selected_path.concat(results.routes[0].overview_path);

                    }
                })

            }
            alert(i)   ////// ADDED ONE LINE
            console.log(selected_path); /// selected_path in console has proper value
            poly.setPath(selected_path);
            poly.setMap(map);

变量i显示为屏幕上的警报,变量selected_pa​​th具有适当的值。有人可以向我解释一下,因为我得不到它。澄清它在firefox中有效,可能不在chrome中。

2 个答案:

答案 0 :(得分:4)

我认为这是由directionsService.route方法的异步行为引起的。它在ajax调用完成后调用回调函数。

因此,当您显示警报时,之后执行代码(console.log)将被推迟,直到您单击“确定”按钮。这是足够的时间让ajax调用完成并填充selected_path变量。在没有警报的版本中没有这样的延迟,因此ajax调用尚未完成,并且很可能在console.log运行之前无法填充selected_path

要解决此问题,您可以做两件事:

  1. 在回调函数中填写selected_path后要执行的代码。
  2. 启动超时以检查它是否已填满,并且仅在有代码时运行代码。
  3. 所以第一个解决方案就是这样做:

     directionsService.route(request, function(results, status) {
       if (status == google.maps.DirectionsStatus.OK) {
          selected_path = selected_path.concat(results.routes[0].overview_path);
    
          alert(i)   ////// ADDED ONE LINE
          console.log(selected_path); /// selected_path in console has proper value
          poly.setPath(selected_path);
          poly.setMap(map);
        }
      })
    

    第二个是:

     directionsService.route(request, function(results, status) {
       if (status == google.maps.DirectionsStatus.OK) {
          selected_path = selected_path.concat(results.routes[0].overview_path);
        }
      })
    
      (function test() {
        if (selected_path.length > 0) {
          alert(i)   ////// ADDED ONE LINE
          console.log(selected_path); /// selected_path in console has proper value
          poly.setPath(selected_path);
          poly.setMap(map);
        } else {
          setTimeout(test, 200);
        }
      })();
    

    如果可能,我会使用第一个。

答案 1 :(得分:1)

这是因为您在异步回调中设置了selected_pathalert(i)需要足够的时间来评估异步回调,这就是它工作的原因。但你不能依赖它(以及你不能依赖setTimeout(function(){console.log(selected_path);}, 0),它应该工作相同),因为异步调用可能需要很长时间。

解决方案是让所有代码都使用selected_path和所有代码,应该在它之后进行回调,如下所示:

directionsService.route(request, function(results, status) {
     if (status == google.maps.DirectionsStatus.OK) {
          var selected_path = selected_path.concat(results.routes[0].overview_path);
          poly.setPath(selected_path);
          poly.setMap(map);
          // ...
     }
});
相关问题