代码在API响应之前执行

时间:2011-04-14 05:37:58

标签: javascript ajax api response

我有一个调用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 个答案:

答案 0 :(得分:1)

首先,请格式化您的代码。

其次,你的代码在响应之前执行是什么意思?如果它取决于$.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]
               });
              }                                 
                                   }
                               });
                           }

                   }

您遇到的问题是,在运行脚本之前,您没有等待所有异步调用返回。这一变化可确保您在继续之前获得最终的预期响应。

话虽如此,您可能想要引入一些错误检查 - 如果未返回响应或您收到错误代码会发生什么?应该检查这些情况。

答案 1 :(得分:1)

您遇到的问题是同步代码与异步代码。您的API请求都会导致进行AJAX(异步)调用 - 这就是您必须提供function(status, response)回调的原因 - 然后您立即(同步)尝试使用这些调用的结果,其中许多可能没有已经制作,更不用说了。

您需要做的是延迟MarkerClusterer代码,直到最后一次API调用返回为止。最简单的方法是在每次响应进入时递减计数器,并在其达到零时触发其余代码。但请注意,在这种情况下,{API}调用返回后才会创建markerClusterer,因此您可能需要添加使用它的代码(或者更好的是调用使用它的函数)在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
});