Неожиданное поведение кода внутри $(document).ready() Должен ли он выполняться последовательно?

Я уже давно использую JavaScript и jQuery. Но я еще не до конца понял, как все это работает. Я приношу извинения, если мой вопрос будет излишним, непонятным и/или просто глупым.

Я использую API Google Maps v3 в сочетании с jQuery (без плагинов, просто jQuery), чтобы заполнить div#googleMap картой Лондона. В дополнение к этому я пытаюсь написать функцию для получения координат заданного адреса (Геокодирование). Что я собираюсь делать с этими координатами, это отдельная история.

Моя проблема заключается в следующем коде:

jQuery(document).ready(function($) {
  mapObject   = initGoogleMaps();
  coordinates = getCoordinates('United Kingdom');

  console.log(coordinates.toString());

  function initGoogleMaps() {
    google.maps.visualRefresh = true;
    map = new google.maps.Map($("#googleMap")[0], {
      center:            new google.maps.LatLng(51.511214, -0.119824),
      zoom:                     10,
      heading:                  0,
      mapTypeId:                google.maps.MapTypeId.ROADMAP,
      disableDefaultUI:         true,
      disableDoubleClickZoom:   true,
      draggable:                false,
      keyboardShortcuts:        false,
      scrollwheel:              false,
      backgroundColor:          'transparent'
    });
    return map;
  }

  function getCoordinates(address) {
    fallback    = 'London, United Kingdom';
    geocoder    = new google.maps.Geocoder();
    address     = typeof(address) == 'string' ? address : fallback;
    coordinates = '';

    geocoder.geocode({ 'address':address },
                     function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        coordinates = results[0].geometry.location;
      } else {
        coordinates = 'Location: "' + address + '" not found.\n' +
                      'Status: ' + status;
      }
    });

    return coordinates;
  }
}); // jQuery(document)

Я использую Chrome DevTools, точнее, Консоль JavaScript, встроенная в Google Chrome.

Когда я обновляю страницу, я получаю следующий вывод:

Coordinates: ↩

Я подумал, может быть, Maps API неудачен в геокодировании местоположения. Но...

  1. Это напечатает сообщение: Location "London Heathrow" not found.
  2. Я объявил coordinates снаружи $.ready() и в консоли, после того как было напечатано пустое сообщение, набрал coordinates, нажал return и выдало: coordinates ▸ M {jb: 55.378051, kb: -3.43597299999999, toString: function, b: function, equals: function…}

Что странно. По моему мнению, идентификатору coordinates присвоено значение пустой строки (''). Почему? Я вызвал функцию getCoordinates() прямо перед тем, как использовать идентификатор coordinates.

Возможно ли, что инструкции внутри $(document).ready(function(){...}) не выполняются в каком-то определенном порядке? Или это из-за задержки при получении results через Maps API? Как получить инструкцию console.log(...) только после того, как значение coordinates будет выбрано и назначено?

Может быть, это какая-то глупая ошибка, которую я не замечаю.


person Zia Ur Rehman    schedule 02.08.2013    source источник
comment
@geocodezip: прошу прощения. Я продолжал думать об этом как о проблеме с jQuery, а не как о проблеме с geocode. Я провел тщательный поиск в Google, клянусь. Но я думаю, что мои условия поиска были совершенно неправильными. Кстати, есть ли способ вернуть результаты?   -  person Zia Ur Rehman    schedule 03.08.2013
comment
Как я уже говорил в своем предыдущем комментарии The geocoder is asynchronous, you can **use** the results in the callback function, you can't return them from it.   -  person geocodezip    schedule 03.08.2013
comment
Я прочитал это. Я думал, что будет какой-то другой способ вернуть данные, которые будут использоваться какой-то другой функцией за пределами области getCoordinates(). Я так понимаю, нет. Ужасно извиняюсь за то, что показался тупицей.   -  person Zia Ur Rehman    schedule 03.08.2013


Ответы (1)


Ваш coordinates = ''; выходит за рамки функции обратного вызова .geocode. Вместо этого вам нужно var coordinates = '';.

person dfockler    schedule 02.08.2013
comment
@dfocker Я понимаю, как это может выходить за рамки. Но я не понимаю, как var должен решить эту проблему. Однако я все равно попробовал это решение. Но это не работает. - person Zia Ur Rehman; 03.08.2013
comment
var извлекает любую переменную, которую вы вызываете, в область действия блока, в котором она находится. Таким образом, переменная coordinates будет той же переменной внутри функции обратного вызова, что и вне функции обратного вызова. Но мой ответ не совсем правильный, geocodezip был правильным в том смысле, что он асинхронный, и вы не можете вернуть значение, которое он вам дает. - person dfockler; 03.08.2013
comment
Независимо от первоначального вопроса, то, что вы только что объяснили, было мне неизвестно. Может вырвано из контекста, но помогает. Ваше здоровье! - person Zia Ur Rehman; 03.08.2013
comment
Я не очень хорошо это объяснил, я бы рекомендовал посмотреть здесь для получения дополнительной/лучшей информации. - person dfockler; 03.08.2013