Код выполняется до ответа API - PullRequest
0 голосов
/ 14 апреля 2011

У меня есть функция, которая вызывает Google Geocoder API для получения широты и долготы.Проблема в том, что ответ приходит слишком поздно после выполнения кода, который зависит от ответа.

Вот мой текущий код.

var prmList = '';
prmList += '{"Empty":"","Criteria":""}';

$.ajax({
    type: "POST",
    url: window.location.pathname + "/GetAddress",
    data: prmList,
    async: false,
    cache: true,
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (msg) {
        var Alladd = eval('(' + msg.d + ')');
        var itemcount = Alladd.returnAddressList.length;

        if (itemcount > 0) {
            for (i = 0; i < itemcount; i++) {
                var geocoder = new google.maps.Geocoder();

                geocoder.geocode({
                    'address': Alladd.returnAddressList[i].Street + "," +
                               Alladd.returnAddressList[i].City + "," +
                               Alladd.returnAddressList[i].State + "," +
                               Alladd.returnAddressList[i].Country
                }, function (results, status) {
                    if (status == google.maps.GeocoderStatus.OK) {
                        var marker = new google.maps.Marker({
                            position: results[0].geometry.location,
                            draggable: true,
                            icon: markerImage
                        });

                        markers.push(marker);
                    }
                });
            }

            var zoom = parseInt(-1, 10);
            var size = parseInt(-1, 10);
            var style = parseInt(-1, 10);

            zoom = zoom == -1 ? null : zoom;
            size = size == -1 ? null : size;
            style = style == -1 ? null : style;

            markerClusterer = new MarkerClusterer(map, markers, {
                maxZoom: zoom,
                gridSize: size,
                styles: styles[style]
            });
        }
    },

    error: AjaxFailed
});

Ответы [ 2 ]

1 голос
/ 15 апреля 2011

Проблема в том, что вы работаете синхронно против асинхронного кода. Ваш API запрашивает все результаты в AJAX (асинхронных) вызовах - вот почему вы должны предоставить function(status, response) обратный вызов - но вы сразу же (синхронно) пытаетесь использовать результаты этих вызовов, многие из которых, возможно, не были сделано пока, не говоря уже о возвращении.

Вам нужно отложить ваш код MarkerClusterer до тех пор, пока не вернется последний вызов API. Самый простой способ сделать это - уменьшать счетчик каждый раз, когда приходит ответ, и запускать остальную часть кода, когда он достигает нуля. Однако обратите внимание, что в этом случае markerClusterer не будет создано до тех пор, пока не будут возвращены ваши вызовы API, поэтому вам может потребоваться добавить код, который его использует (или, что еще лучше, вызов функции, которая его использует) в низ createCluster ниже.

var prmList = '';
prmList += '{"Empty":"","Criteria":""}';

$.ajax({
    type: "POST",
    url: window.location.pathname + "/GetAddress",
    data: prmList,
    async: false,
    cache: true,
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (msg) {
        var Alladd = eval('(' + msg.d + ')');
        var itemcount = Alladd.returnAddressList.length;

        if (itemcount > 0) {
            // createCluster contains all the code which was below the for loop
            function createCluster() {
                var zoom = parseInt(-1, 10);
                var size = parseInt(-1, 10);
                var style = parseInt(-1, 10);

                zoom = zoom == -1 ? null : zoom;
                size = size == -1 ? null : size;
                style = style == -1 ? null : style;

                markerClusterer = new MarkerClusterer(map, markers, {
                    maxZoom: zoom,
                    gridSize: size,
                    styles: styles[style]
                });
            }

            for (i = 0; i < itemcount; i++) {
                var geocoder = new google.maps.Geocoder();

                geocoder.geocode({
                    'address': Alladd.returnAddressList[i].Street + "," +
                               Alladd.returnAddressList[i].City + "," +
                               Alladd.returnAddressList[i].State + "," +
                               Alladd.returnAddressList[i].Country
                }, function (results, status) {
                    if (status == google.maps.GeocoderStatus.OK) {
                        var marker = new google.maps.Marker({
                            position: results[0].geometry.location,
                            draggable: true,
                            icon: markerImage
                        });

                        markers.push(marker);
                    }

                    // Decrement the item counter, then check if it's 0.
                    // Using itemcount doesn't screw up the for loop
                    // because this isn't executed until much later!
                    if (!--itemcount) createCluster();
                });
            }

        }
    },

    error: AjaxFailed
});
1 голос
/ 14 апреля 2011

Во-первых, пожалуйста, отформатируйте ваш код.

Во-вторых, что вы имеете в виду, что ваш код выполняется перед ответом?Если это зависит от возврата вызова $.ajax, просто включите эту функцию в продолжение success.

Ах, я думаю, я вижу вашу проблему -

Попробуйте это:

var itemcount = Alladd.returnAddressList.length;
if (itemcount > 0) {                           
    for (i = 0; i < itemcount; i++) {
        var geocoder = new google.maps.Geocoder();
        geocoder.geocode({
            'address': Alladd.returnAddressList[i].Street + "," + <br>Alladd.returnAddressList[i].City + "," + Alladd.returnAddressList[i].State + "," + Alladd.returnAddressList[i].Country
            }, function (results, status) {                                   
               if (status == google.maps.GeocoderStatus.OK) {
                   var marker = new google.maps.Marker({
                       position: results[0].geometry.location,
                       draggable: true,
                       icon: markerImage
                });
                markers.push(marker); 
                if(i == itemcount-1)
                {
                    var zoom = parseInt(-1, 10);
                    var size = parseInt(-1, 10);
                    var style = parseInt(-1, 10);
                    zoom = zoom == -1 ? null : zoom;
                    size = size == -1 ? null : size;
                    style = style == -1 ? null : style;               
                    markerClusterer = new MarkerClusterer(map, markers, {
                    maxZoom: zoom,
                    gridSize: size,
                    styles: styles[style]
               });
              }                                 
                                   }
                               });
                           }

                   }

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

Сказав это, вы можете ввести некоторую проверку ошибок - что произойдет, если ответ не будет возвращен или вы получите код ошибки?Все эти случаи должны быть проверены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...