2013-11-11 4 views
0

Я подсчитываю кратчайший путь к точке назначения из разных точек происхождения с помощью google maps api. Я решил сделать это так: (подсчитывайте каждую пару точек, чем сохраняйте результаты в массиве, а затем проверьте в конце, что лучше). Но у меня проблема с обратным вызовом - потому что комментарии говорят, что массив всегда равен нулю, потому что этот код выполняется перед всеми запросами, чтобы подсчитать длину маршрута.JavaScript - обратный вызов - ожидание завершения нескольких функций

function foo(){ 
var directionsService = new google.maps.DirectionsService(); 
var destination = new google.maps.LatLng(x,y); 
var arrayOfRes= []; 

for(var index in originPoints){ 
    var request = { 
     origin:originPoints[index].marker.position, 
     destination:destination, 
     travelMode: google.maps.TravelMode.DRIVING 
    }; 
    directionsService.route(request, function(result, status) { 
      if (status == google.maps.DirectionsStatus.OK) { 
       var res = {}; 
       res.length = result.routes[0].legs[0].distance.value; 
       res.index = index; 
       res.result = result; 
       arrayOfRes.push(res); 
      } 
    }); 
} 
    //here arrayOfRes.length is always 0 
if(arrayOfRes.length>1) 
{ 
    var bestResult = arrayOfRes[0]; 

    for(var i = 1; i < arrayOfRes.length; i++) 
    { 
     if(bestResult.length > arrayOfRes[i]) 
      bestResult = arrayOfRes[i]; 
    } 

    console.log("Best is" + bestResult.length); 
} 
else if(arrayOfRes.length ==1) 
{ 
    var bestResult = arrayOfRes[0]; 
} 
} 

Как написать функцию с обратным вызовом, чтобы она дождалась завершения всех запросов?

+1

dude..common..you можете обрезать вопрос .. сделайте это короче, вы определенно получите больше ответов, когда попросите что-то более простым способом. –

+0

На этот вопрос был дан ответ много раз. Сделайте все возможное и попытайтесь найти ответ. – putvande

+0

Вы, вероятно, должны быть знакомы с обещаниями, обратными вызовами и асинхронным JavaScript в целом. –

ответ

1

Запросы Google подобны асинхронным, поэтому вам необходимо написать асинхронный код, который означает ТОЛЬКО работа с возвращаемыми данными из обратного вызова.

В вашей функции обратного вызова, которая возвращает маршрут, вам необходимо проверить, является ли это ответом на последний запрос. Если это так, то ваш массив имеет все результаты, и вы можете обработать массив.

Предполагая, что originPoints массив, вы могли бы сделать это следующим образом:

var arrayOfRes = []; 
for (var index = 0; index < originPoints.length; ++index) { 
    var request = { 
     origin:originPoints[index].marker.position, 
     destination:destination, 
     travelMode: google.maps.TravelMode.DRIVING 
    }; 
    directionsService.route(request, function(result, status) { 
     if (status == google.maps.DirectionsStatus.OK) { 
      var res = {}; 
      res.length = result.routes[0].legs[0].distance.value; 
      res.index = index; 
      res.result = result; 
      arrayOfRes.push(res); 

      // check if all data has arrived 
      if (arrayOfRes.length === originPoints.length) { 
       // put code here to process arrayOfRes 
      } 
     } 
    }); 
} 

Примечание: JavaScript не имеет возможности сделать свой код ожидания для всех запросов, чтобы сделать, а затем продолжить - таким образом, вы должны использовать асинхронный стиль программирования с потоком кода, продолжающимся от обратного вызова.

Примечание: поскольку directionsService.route является асинхронным вызовом, он будет называть его обратным вызовом в будущем. Тем временем вы продолжите выполнение JS. Это означает, что код, который появляется сразу после этого блока кода, будет выполняться до того, как будут завершены вызовы ajax и до заполнения arrayOfRes. Таким образом, ТОЛЬКО место, где вы можете безопасно использовать данные arrayOfRes, находится в самом обратном вызове или в функции, вызываемой из обратного вызова.

Смежные вопросы