Пытаюсь упрощенно решить задачу коммивояжёра.
Для этого считаю расстояния от начальной (корневой) точки (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
Вопрос: правильно ли я делаю?
Если да, то почему не выводится сообщение "Всё обработано", а если нет - как делать нужно?