JQuery асинхронный AJAX-запрос и проблема с возвращаемым значением (область действия, закрытие) - PullRequest
0 голосов
/ 28 мая 2010

Код не работает из-за асинхронного запроса и проблемы с областью видимости переменной. Я не могу понять, как решить это. Измените метод $ .ajax на async: false - не вариант. Я знаю о замыканиях, но как я могу реализовать это здесь - не знаю. Я видел все темы о замыканиях в js и jQuery async, но все еще ничего. Помогите, пожалуйста. Вот код:

var map = null;
var marker;
var cluster = null;

function refreshMap() 
{
    var markers = [];  
    var markerImage = new google.maps.MarkerImage('/images/image-1_32_t.png', new google.maps.Size(32, 32));

    $.get('/get_users.php',{},function(data){
        if(data.status == 'error')
            return false;

        var users = data.users; // here users.length = 1 - this is ok;  
        for(var i in users)
        {
            //here I have every values from users - ok
            var latLng = new google.maps.LatLng(users[i].lat, users[i].lng);
            var mark = new google.maps.Marker({
                position: latLng,
                icon: markerImage
         });

             markers.push(mark);
             alert(markers.length); // length 1
        }

    },'json');

    alert(markers.length); // length 0  
    //if I have alert() above - I get result

    cluster = new MarkerClusterer(map, markers, 
    {
        maxZoom: null,
        gridSize: null
    });
}

Спасибо.

Ответы [ 2 ]

1 голос
/ 28 мая 2010

Просто переместите этот код:

cluster = new MarkerClusterer(map, markers, 
{
    maxZoom: null,
    gridSize: null
});

В функцию обратного вызова (где находится ваше первое предупреждение)

Проблема в том, что при асинхронном запросе код продолжит выполняться, даже еслизапрос не завершен.Таким образом, ваша переменная markers не будет установлена ​​правильно, пока не будет выполнена ваша функция анонимного обратного вызова.

0 голосов
/ 28 мая 2010

Весь ваш код, который имеет дело с markers, должен быть в вашей функции обратного вызова. Эта строка кода:

alert(markers.length); // length 0  

выполняется до , когда возвращается вызов Ajax (т.е. до выполнения обратного вызова).


Это означает, что ваш код должен выглядеть примерно так:

$.get('/get_users.php',{},function(data){
    if(data.status == 'error')
        return false;

    var users = data.users; // here users.length = 1 - this is ok;  
    for(var i in users)
    {
        //here I have every values from users - ok
        var latLng = new google.maps.LatLng(users[i].lat, users[i].lng);
        var mark = new google.maps.Marker({
            position: latLng,
            icon: markerImage
         });

         markers.push(mark);
         alert(markers.length); // length 1

         cluster = new MarkerClusterer(map, markers, 
                   {
                           maxZoom: null,
                           gridSize: null
                   });

         // more with cluster here
     }
},'json');

Если вы устанавливаете или изменяете переменные в обратном вызове Ajax, не полагайтесь на их значения вне обратного вызова.

...