简体   繁体   中英

callback after getJSON in for loop

So i'm doing a getJSON request in a for loop. In the getJSON function callback I push the values into a global array.

Now accessing that global array outside the for loop is not possible due the fact getJSON is async i read...

I tried making flags and other callback functions but it looks like even the for loop ends faster (even with je getJSON function insde the for loop) than the getJSON requests..

function initMap(){

// Address value variables
var country;
var city;
var addresses = [];
var locations = [];

// Google maps variables
var myOptions = {
    zoom: 5,
    center: new google.maps.LatLng(0, 0),
    mapTypeId: 'terrain',
    scrollwheel: false,
    navigationControl: true,
    mapTypeControl: true,
    scaleControl: true,
    draggable: true
};
var marker;
var bounds = new google.maps.LatLngBounds();

// Get country city values
$('li.deal-itinerary-item').each(function(){
    country = $(this).data('country');
    city = $(this).data('city');
    if( country && city ){
        addresses.push(country + ' ' + city);
    }
});

var map = new google.maps.Map($('#map_canvas')[0], myOptions);

for (var x = 0; x < addresses.length; x++) {

    $.getJSON('http://maps.googleapis.com/maps/api/geocode/json?address='+addresses[x]+'&sensor=false', null, function (data) {

        var p = data.results[0].geometry.location;
        var latlng = new google.maps.LatLng(p.lat, p.lng);

        locations.push({lat: p.lat, lng: p.lng});

        marker = new google.maps.Marker({
            position: latlng,
            map: map
        });

        bounds.extend(marker.position);

    });

}

// CONSOLE LOG NOT WORKING HERE
console.log(locations);

map.fitBounds(bounds);

zoomChangeBoundsListener = 
google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
    if (this.getZoom()){
        this.setZoom(6);
    }
});
setTimeout(function(){google.maps.event.removeListener(zoomChangeBoundsListener)}, 2000);

};
google.maps.event.addDomListener(window, 'load', initMap);

So first the variables, then i get Country name and City name out of data attribute on divs inside the dom. Then I itterate over the addresses to get the lat/lng values for the markers (and the polylines). If i console.log the locations variable at the end, it shows an empty array in the console, but when I click the array is filled (probably cause the array gets filled after displaying it)..

PS Since I can't yet post images, the console.log() displays just [ ] and when i click on the array it show the objects just fine...

0  Object { lat=53.3498053,  lng=-6.2603097}
1  Object { lat=53.3498053,  lng=-6.2603097}
2  Object { lat=53.3498053,  lng=-6.2603097}
3  Object { lat=53.717856,  lng=-6.3560985}
4  Object { lat=54.5982897,  lng=-5.8925882}
5  Object { lat=53.59944249999999,  lng=-7.850193999999999}
6  Object { lat=54.6541972,  lng=-8.110546}
7  Object { lat=54.9558392,  lng=-7.7342787}

Any help on this is highly appriciated since im stuck on this since yesterday...

Try:

var count_getJSONs_done = 0;
for (var x = 0; x < addresses.length; x++) {

    $.getJSON('http://maps.googleapis.com/maps/api/geocode/json?address='+addresses[x]+'&sensor=false', null, function (data) {

        var p = data.results[0].geometry.location;
        var latlng = new google.maps.LatLng(p.lat, p.lng);

        locations.push({lat: p.lat, lng: p.lng});

        marker = new google.maps.Marker({
            position: latlng,
            map: map
        });

        bounds.extend(marker.position);

    })
      .always(function() {
         count_getJSONs_done++;
         if (count_getJSONs_done == addresses.length) // the last getJSON in the loop is completed
           processLocations();
      });

}

According to http://api.jquery.com/jquery.ajax/ , section: "Callback Function Queues", the .always callback will be invoked after success handler of getJSON .

Updated: Notice, that this code works even if some of the getJSON have failed.

Try this logic

for (var x = 0; x < addresses.length; x++) {

$.getJSON('http://maps.googleapis.com/maps/api/geocode/json?address='+addresses[x]+'&sensor=false', null, function (data) {

    var p = data.results[0].geometry.location;
    var latlng = new google.maps.LatLng(p.lat, p.lng);

    locations.push({lat: p.lat, lng: p.lng});

    marker = new google.maps.Marker({
        position: latlng,
        map: map
    });

    bounds.extend(marker.position);

    if(locations.length == addresses.length){ // all locations gathered
        console.dir(locations)
    }
});

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM