Клуб API Карт

YMaps.Geocoder поясните по выполнению функции.

Пост в архиве.
rbaskov
1 ноября 2010, 16:18

Привет, есть небольшое недопонимание.

Мне нужно получить координаты объекта. Смотрю как отрабатывает эта функция(в MSE) и возникает ступор. В начале почему-то мы проскакиваем событие "YMaps.Events.observe(geocoder, geocoder.Events.Load, function ()", идем в конец. Потом снова уже попадаем в "YMaps.Events.observe" и получаем значение переменных val1 и val2. Почему так? Что может быть?

 var val1, val2;

function showAddress(find) {
debugger;
var geocoder = new YMaps.Geocoder(find, { results: 1});
debugger;
YMaps.Events.observe(geocoder, geocoder.Events.Load, function () {
if (this.length()) {
geoResult = this.get(0);
val1 = geoResult._point.__lng;
val2 = geoResult._point.__lat;
}
else {
alert("Ничего не найдено")
}
});
YMaps.Events.observe(geocoder, geocoder.Events.Fault, function (geocoder, error) {
alert("Произошла ошибка: " + error);
})
};
12 комментариев
Функция срабатывает при наступлении события.
Т.е. это не линейный кусок кода.
Если объяснять по простому, то сначала на событие ставится некий обработчик (функция). И при наступлении этого события функция вызывается.

советую пчитать для общего развития про события, обработчики, асинхроность и потоки без привязки к какому-либо языку.
NeWMaN вам правильно пояснил.

От себя хочу добавить небольшой совет: не исполльзуйте "педали" (т. е. вызов методов и обращение к полям через подчеркивание). От версии к версии они могут меняться и ваш код может оказаться в итоге или неработоспособным.
Во избежания такой проблемы используйте методы, описанные в документации.
Таким образом ваш код:

val1 = geoResult._point.__lng;
val2 = geoResult._point.__lat;

Лучше заменить на:

var point = geoResult.getGeoPoint();
val1 = poing.getLng();
val2 = point.getLat();

Хм, функцию showAddress(find) мы вызываем до тех пор, пока в массиве значений find[] есть данные.


В моих "мечтах" это выглядело примерно так:


var i=0;


var XY[];


while (i < find.length){


XY[i] = showAddress(find[i]);


}


Пишу я на C sharp, вызывая функцию через InvokeScript. В данном случае мне надо копать в сторону "YMaps.Events.observe"?


 

Черт, или же все таки дело в window.onLoad?
Дело в нехватке теории ;)
Указаный пример не сработает.
Функция showAddress что вы привели раньше работает через глобальные переменные.
В результате получится что запросов сделано много, обработчиков тоже много. А работают они все через одни и те же переменные.
Обычно для такого варианта приходится извращаться с массивами и передачей в обработчик идекса элемента, в который писать результат.

Для вашего варианта возможно стоит обратить внимание на то что с геокодером можно "общаться" через HTTP и оставить в стороне JavaScript

Сделал как-то так: "извратился с массивами", а точнее со стеком.



 


Криво, но за неимением "хватки теории" пока будем использовать этот вариант :)


Спасибо.

Красиво, но неправильно, к сожалению.
Никто не гарантирует вам что обработчики событий сработают именно в том порядке в каком они были поставлены. Там совсем не FIFO, а "кто быстрей тот и первый" ;)

Например, запрос по адресу номер 1 может выполнятся дольше чем запрос по адресу номер 2. В результате в стек сначала попадут точки для адреса 2 (но с индексом 1), а потом точки для адреса 1 (но уже с индексом 2). В результате адреса индексы адресов не будут соответствовать индексам координат.

Для количества точек N может получится еще фееричней. Поэтому я и говорил про передачу индекса в обработчик.
Понял, проверю. Попробую немного по другому переделать. Просто с использованием push для меня было быстрей :) Но есть вариант все сделать иначе.
Действительно, в некоторых местах наблюдается смещение координат... Будем исправлять :)
Может вам поможет пример множественного геокодирования?
http://api.yandex.ru/maps/jsapi/examples/multiplygeocoding.html
Спасибо, смотрел уже. Сделал с индексами, все теперь совпадает, будем нагружать сервер яндекс карт ;-)