@magary4

Геокодинг массива адресов?

получаю массив адресов, нужно каждый геокодировать-получить координаты и добавить в новый массив уже с координатами
пахнет callbackhellom
как сделать

for (var i = 0; i < items.length; i++) {
                    var item = items[i];
                    GMaps.geocode({
                        address: item.address+" "+item.city+" "+item.zip,
                        callback: function(results, status) {
                            if (status == 'OK') {
                                var latlng = results[0].geometry.location;
                                map.setCenter(latlng.lat(), latlng.lng());

                                markers_data.push({
                                    id: item.id,
                                    lat : latlng.lat(),
                                    lng : latlng.lng(),
                                    title : item.name,
                                    icon : {
                                        size : new google.maps.Size(32, 32),
                                        url : icon
                                    },
                                    infoWindow: {
                                        content : ''
                                    }
                                });
                            }
                        }
                    });


после того как все будут геокодированы - нужно вызвать общий колбэк и добавить на карту все маркеры одним вызовом

кроме того у меня внутри колбэка GMaps.geocode callback недоступен обьек item

помогите
  • Вопрос задан
  • 338 просмотров
Решения вопроса 1
VladimirZhid
@VladimirZhid
Нравится делать что-то интересное и полезное.
Если нет желания тащить async, то можно как-то так:
var pro = new Promise(function(resolve, reject){
    //...your code
    callback: function(results, status) {
        if (status == 'OK') {
            // тест на кол-во записей в markers_data или на последнюю итерацию цикла
            //если так то resolve(markers_data)
        }
    }
    //...
}).then(function(markers_data){
    //...
})

Если нет желания использовать промисы то callbackhell велком!
А item должен быть виден...

Ну можно еще событие кидать. Использовать какой-нибудь EventEmitter, ну или на window...
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
lazalu68
@lazalu68
Salmon
Кажется, async.map как раз для этого

Если задача одна и вся библиотека не нужна, аналог async.map реализуется довольно просто.

Бтв, caolan вроде бы без промисов справляется с этим, в простейшей реализации как-то
так
var list_of_items_to_process = [ 1, 2, 3, 4, 5 ];

function asyncMap(list, exec, callback) {
	var processed = 0;

	list.forEach(function(current, index, array) {
		exec(current, index, array, innerCallback.bind(index));
	})

	function innerCallback(result) {
		list[this] = result;
		processed++;
		if (processed === list.length) {
			callback(list);
		}
	}
}

function processor(value, index, array, callback) { 
	var result;
	setTimeout(function() { 
		result = value*Math.round(Math.random()*10);
		console.log(result)
		callback(result); 
	}, 500*value); 
}

function mainCallback(values) {
	console.log(values);
}

asyncMap(list_of_items_to_process, processor, mainCallback)


Если я ничего не напутал, то после того, как вы сформируете items, вам достаточно будет выполнить
это
function asyncMap(list, exec, callback) {
  var processed = 0;

  list.forEach(function(current, index, array) {
    exec(current, index, array, innerCallback.bind(index));
  })

  function innerCallback(result) {
    list[this] = result;
    processed++;
    if (processed === list.length) {
      callback(list);
    }
  }
}

function processor(value, index, array, cb) {
  GMaps.geocode({
    address: value.address + " " + value.city + " " + value.zip,
    callback: function(results, status) {
      if (status == 'OK') {
        cb(results);
      } else {
        cb(false);
      }
    }
  });
}

function mainCallback(values) {
  values.forEach(function(value) {
    if (!value) return;

    var latlng = results[0].geometry.location;
    map.setCenter(latlng.lat(), latlng.lng());

    markers_data.push({
      id: value.id,
      lat: latlng.lat(),
      lng: latlng.lng(),
      title: value.name,
      icon: {
        size: new google.maps.Size(32, 32),
        url: icon
      },
      infoWindow: {
        content: ''
      }
    });
  });
}

asyncMap(items, processor, mainCallback)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы