变量在 Javascript 中的可见性

variables visibility in Javascript

本文关键字:可见性 Javascript 变量      更新时间:2023-09-26

这是我的示例代码

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);

在这种情况下,控制台中的selected_path是 []。当我在控制台.log(selected_path(之前添加警报(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_path 具有适当的值。有人可以向我解释一下吗,因为我不明白。澄清一下,它在火狐中有效,可能不适用于 chrome。

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

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

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

    将填充
  1. selected_path后要执行的代码也放在回调函数中。
  2. 启动超时以检查它是否已填充,并且仅在填充时运行代码。

因此,第一个解决方案是这样做:

 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);
    }
  })();

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

这是因为您在异步回调中设置了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);
          // ...
     }
});