Клуб API Карт

странное поведение геокодера

Пост в архиве.

var ordersCollection = new YMaps.GeoObjectCollection();
for (i in aResults) {
    order = aResults[i];
    number = order['number'];
    dAddress = order['dAddress'];

    //alert(1);
    geocoder = new YMaps.Geocoder(dAddress, {results: 1});
    YMaps.Events.observe(geocoder, geocoder.Events.Load, function () {
        if (this.length()) {
            geoResult = this.get(0);
            geoPoint = geoResult.getGeoPoint();
            placemark = new YMaps.Placemark(geoPoint, {style: s, style:styleKeys[0]} );
            placemark.setIconContent(number);
            placemark.description = 'описание';
            ordersCollection.add(placemark);
            setTimeout('podojdem', 5000);
        }else {
            alert("Ничего не найдено");
        }
    });
 
}
map.addOverlay(ordersCollection);

-------------
function podojdem() {
    return 1;
}


вот этот код создает точки на карте с нужными координатами, но вот номер

placemark.setIconContent(number);

вставляется один и тот же

Стоит раскомментировать алерт как все сразу хорошо. Пробовал setTimeout('podojdem', 5000) - вообще как то странно начинает работать. Сначала выведется одна - две точки, потом остальные разом. Но все равно всё с одним и тем же номером.

Причем номер выводится только последнего заказа.

2 комментария
Sergey Konstantinov
28 января 2016, 09:01
В JavaScript'е вложенная функция (в данном случае, та, что объявлена внутри YMaps.Events.observe) вызывается в контексте исполнения внешней функции. Поскольку внешняя функция была вызвана один раз, в памяти сохранится только один контекст ее исполнения - в этом контексте значение переменной number будет соответствовать последней итерации цикла. То же самое касается переменной geocoder - в памяти сохранится только последнее ее значение (здесь так же стоит обратить внимание на то, что в JavaScript областью видимости переменной является функция, в которой она объявлена, а не блок). Для того, чтобы избежать такой проблемы, необходимо объявить функцию, принимающую в качестве параметра number и geocoder, и возвращающую функцию-обработчик загрузки геокодера. Т.е. примерно так: function getListener(number, geocoder) { return function () { if (geocoder.length()) { geoResult = geocoder.get(0); geoPoint = geoResult.getGeoPoint(); placemark = new YMaps.Placemark(geoPoint, {style: s, style:styleKeys[0]} ); placemark.setIconContent(number); placemark.description = 'описание'; ordersCollection.add(placemark); setTimeout('podojdem', 5000); }else { alert("Ничего не найдено"); } } } } YMaps.Events.observe(geocoder, geocoder.Events.Load, getListener(number, geocoder));
Хороший ответ)! Спасибо. сразу все ок стало.