S
S
squrre12014-05-31 11:41:35
JavaScript
squrre1, 2014-05-31 11:41:35

Asynchronous calculation of routes using the Yandex Map API (deferred.promise)?

I'm trying to solve the traveling salesman problem in a simplified way.
To do this, I count the distances from the initial (root) point (myPointRoot) to others (elements of the array myPoints)

The essence of the problem:
At the input there is a point myPointRoot and an array of points myPoints
At the output, you need an array myLenghts with distances to them

To calculate the distance, use the route from the Yandex Map API - api.yandex.ru/maps/doc/jsapi/2.0/dg/concepts/router.xml
But this thing is asynchronous.

Here's my solution, which doesn't work, and it's quite possible that it's completely wrong:

Since route() is an asynchronous function, routes can be calculated in any order and it is not known when they are calculated.
Therefore, we need an array of promise objects (I use them from JQuery) - promiseArray. In the loop, we fill it, and when each route is calculated, it will execute .resolve() for its promise.
And immediately after the loop, we hang up processing using JQuery.when(), which will be executed only when all routes in the promiseArray array change their status to " resolve".
In fact, the route function itself returns a promise object, and you can put it in the promiseArray itself. But he, some of his own, Yandex, and I could not write a handler that will work when all the elements of the promiseArray are fulfilled.

Here is the whole code (you can play around) - jsfiddle.net/4xfxR/1

Here is a piece:

// запускаемся только после загрузки 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



Question: Am I doing the right thing?
If so, why is the message "Everything processed" not displayed, and if not, how should I do it?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question