Сумасшедшее поведение JavaScript, которое я когда-либо видел - PullRequest
8 голосов
/ 11 мая 2010

И это что-то говорит. Это основано на примере Google Maps для Направлений в API Карт v3.

<html> 
<head> 
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
<title>Google Directions</title> 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript"> 
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var map;


function initialize() {
    directionsDisplay = new google.maps.DirectionsRenderer();

    var myOptions = {
      zoom:7,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    }

    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    directionsDisplay.setMap(map);
    directionsDisplay.setPanel(document.getElementById("directionsPanel"));
}

function render() {
    var start;

    if(navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
          start = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
        }, function() {
          handleNoGeolocation(browserSupportFlag);
        });
      } else {
        // Browser doesn't support Geolocation
        handleNoGeolocation();
    }

    alert("booga booga");


    var end = '<?= $_REQUEST['destination'] ?>';
    var request = {
        origin:start, 
        destination:end,
        travelMode: google.maps.DirectionsTravelMode.DRIVING
    };
    directionsService.route(request, function(response, status) {
      if (status == google.maps.DirectionsStatus.OK) {
        directionsDisplay.setDirections(response);
      }
    });
}

</script> 
</head> 
<body style="margin:0px; padding:0px;" onload="initialize()"> 
<div><div id="map_canvas" style="float:left;width:70%; height:100%"></div> 
<div id="directionsPanel" style="float:right;width:30%;height 100%"></div> 
<script type="text/javascript">render();</script>
</body> 
</html>

Видите это "alert ('booga booga')" там?

Имея это, все это работает фантастически. Прокомментируйте это, и начало var будет неопределенным, когда мы нажмем на строку, чтобы определить запрос var.

Я обнаружил это, когда убрал предупреждение, которое я вставил туда, чтобы показать мне значение var start, и оно перестало работать. Если я действительно прошу его предупредить меня о значении var start, он говорит, что он не определен, НО он имеет действительное (и точное!) Значение, когда мы определяем var request несколькими строками позже.

Я подозреваю, что это проблема синхронизации - как асинхронное, что-то успевает завершиться в фоновом режиме в тот момент, когда мне требуется отключить предупреждение. Есть мысли об обходных путях?

Ответы [ 2 ]

16 голосов
/ 11 мая 2010

То, что вы считаете правильным, navigator.geolocation.getCurrentPosition() - асинхронный вызов завершен, пока вы отклоняете это предупреждение. Чтобы это исправить, вам нужно продолжить работу либо с помощью функции обратного вызова. Чтобы сделать это, переставьте ваш код, чтобы он появлялся после его завершения, например:

function render() {
    if(navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
          var start = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
          var end = '<?= $_REQUEST['destination'] ?>';
          var request = {
              origin:start, 
              destination:end,
              travelMode: google.maps.DirectionsTravelMode.DRIVING
          };
          directionsService.route(request, function(response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
              directionsDisplay.setDirections(response);
            }
          });
        }, function() {
          handleNoGeolocation(browserSupportFlag);
        });
      } else {
        // Browser doesn't support Geolocation
        handleNoGeolocation();
    }
}
7 голосов
/ 11 мая 2010

«Асинхронное что-то» - это вызов getCurrentPosition. Предупреждение занимает некоторое время, так что вызов может завершиться и вызвать обратный вызов, который устанавливает значение «start».

Вы можете попробовать переместить весь кусок кода, начиная с того места, где вы определяете «запрос», до обратного вызова в getCurrentPosition. Это задержит его до тех пор, пока «start» определенно не будет установлен в полезное значение.

edit yes, как показывает Ник в своем примере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...