Асинхронный расчет маршрутов при помощи API Yandex Map (deferred.promise)?

Пытаюсь упрощенно решить задачу коммивояжёра.
Для этого считаю расстояния от начальной (корневой) точки (myPointRoot) до других (элементы массива myPoints)

Суть задачи:
На входе есть точка myPointRoot и массив точек myPoints
На выходе нужен массив myLenghts с расстоями до них

Для рассчета расстояния используется route из Yandex Map API - api.yandex.ru/maps/doc/jsapi/2.0/dg/concepts/router.xml
Но, эта штука асихронная.

Далее идет моё решение, которое не работает и вполне возможно что это вообще совсем неправильно:

Так как route() - асинхронная функция, маршруты могут рассчитаться в любом порядке и неизвестно когда рассчитаются.
Поэтому нужен массив promise-объектов (я использую их из JQuery) - promiseArray. В цикле мы его заполняем, и когда каждый маршрут рассчитается, он для своего promise выполнит .resolve()
А сразу после цикла, вешаем обработку при помощи JQuery.when() которая выполнится только тогда когда все маршруты в массиве promiseArray изменят свой статус на "resolve".
Вообще-то, сама функция route возвращает promise-объект и его самого можно засунуть в массив promiseArray. Но он, какой-то свой, яндексовский и я не смог написать обработчик, который сработает когда все элементы promiseArray выполнятся.

Вот тут весь код (можно поиграться) - jsfiddle.net/4xfxR/1

Вот кусок:
// запускаемся только после загрузки yandex.api
    ymaps.ready(init);
    
    var promiseArray = []; // массив обещаний
    var myRootPoint = [52.290139, 104.279331]; //начальная точка
    var myPoints = [
	[52.284889, 104.282771],
	[52.283527180127, 104.26076298926],
	[52.263199, 104.19824]
	
    ];

    function init() { 
	for(var i = 0; i<myPoints.length; i++) {
	    var coor = [myRootPoint, myPoints[i]];
	    // пришлось делать замыкание
	    // потому что иначе i не запоминается
	    var fn = (function() {
		var dfd = new $.Deferred();
		promiseArray.push(dfd.promise());

		var myI = i; // сохраняем в замыкании ID элемента
		var myCoor = coor; // сохраняем в замыкании координаты
		ymaps.route(myCoor).then(
		    function (route) {
			writeText('маршрут='+myI+" расстояние=" +route.getLength());
			// "завершаем" promise-object
			promiseArray[myI].resolve();
		    },
		    function (error) {
			promiseArray[myI].reject();
			writeText('Возникла ошибка: ' + error.message);
		    }
		); //end ymaps.route
	    }); //end fn
	    fn(); // выполняем "замыкание"
	} //end for

	$.when.apply($, promiseArray).then(function(){
	    // не срабатывает этот кусок 
	    console.log(promiseArray);
	    writeText('Всё обработано!');
	});
    } //end init



Вопрос: правильно ли я делаю?
Если да, то почему не выводится сообщение "Всё обработано", а если нет - как делать нужно?
  • Вопрос задан
  • 5332 просмотра
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы