Javascript/jQuery—在运行其余部分之前等待函数完成

Javascript/jQuery—在运行其余部分之前等待函数完成,javascript,jquery,Javascript,Jquery,嗨,我有一个按钮,当它被点击时会触发一个函数。该函数执行一些操作(对纬度/经度进行反向地理编码),然后用值填充隐藏表单输入 在我需要的其余代码执行之前,我需要输入正确的值,有什么方法可以做到这一点吗?目前我有 $('.addButton').click(function() { //first run the reverse geocode to update the hidden location input with the readable address reverse

嗨,我有一个按钮,当它被点击时会触发一个函数。该函数执行一些操作(对纬度/经度进行反向地理编码),然后用值填充隐藏表单输入

在我需要的其余代码执行之前,我需要输入正确的值,有什么方法可以做到这一点吗?目前我有

$('.addButton').click(function() { 
    //first run the reverse geocode to update the hidden location input with the readable address
    reversegeocode();
    var location = $("#location").val();//the value I need
    $.post("<?php echo $this->webroot;?>locations/add", {location:location})
        .done(function (data) {
            $("#locationsHolder").html(data);
        });
});

您需要在
reversegeocode
函数中使用回调函数。

与使用ajax的方法完全相同:)


由于
reversegeocode
是一种异步方法,因此需要使用基于回调的解决方案
reversegeocode
应接收回调方法作为参数,然后在地理编码完成后调用回调

$('.addButton').click(function () {
    //pass a callback to reversegeocode which will get called once the geocoding is completed
    reversegeocode(function (location) {
        //the callback receives the location as a parameter
        $.post("<?php echo $this->webroot;?>locations/add", {
            location: location
        })
            .done(function (data) {
            $("#locationsHolder").html(data);
        });
    });
});

function reversegeocode(callback) {
    var lat = $('#lattitude').val();
    var lng = $('#longitude').val();
    var latlng = new google.maps.LatLng(lat, lng);
    geocoder.geocode({
        'latLng': latlng
    }, function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            if (results[0]) { //http://stackoverflow.com/questions/8082405/parsing-address-components-in-google-maps-upon-autocomplete-select
                var address_components = results[0].address_components;
                var components = {};
                jQuery.each(address_components, function (k, v1) {
                    jQuery.each(v1.types, function (k2, v2) {
                        components[v2] = v1.long_name
                    });
                })
                var output = '';
                var needAcomma = false;
                if (components.route != undefined) {
                    output += components.route;
                    needAcomma = true;
                }
                if (components.locality != undefined) {
                    if (needAcomma) {
                        output += ', ';
                    }
                    output += components.locality;
                    needAcomma = true;
                }
                if (components.administrative_area_level_1 != undefined) {
                    if (needAcomma) {
                        output += ', ';
                    }
                    output += components.administrative_area_level_1;
                    needAcomma = true;
                } else if (components.administrative_area_level_2 != undefined) {
                    if (needAcomma) {
                        output += ', ';
                    }
                    output += components.administrative_area_level_2;
                    needAcomma = true;
                } else if (components.administrative_area_level_3 != undefined) {
                    if (needAcomma) {
                        output += ', ';
                    }
                    output += components.administrative_area_level_3;
                    needAcomma = true;
                }
                $("#location").val(output);
                //call the callback
                callback(output);
            } else {
                alert('No results found');
            }
        } else {
            alert('Geocoder failed due to: ' + status);
        }
    });
}
$('.addButton')。单击(函数(){
//将回调传递给reversegeocode,一旦地理编码完成,就会调用它
反向编码(功能(位置){
//回调函数将该位置作为参数接收
$.post(“位置/添加”{
地点:地点
})
.完成(功能(数据){
$(“#locationsHolder”).html(数据);
});
});
});
函数反转代码(回调){
var lat=$('#latitude').val();
var lng=$(“#经度”).val();
var latlng=新的google.maps.latlng(lat,lng);
地理编码({
“latLng”:latLng
},功能(结果、状态){
if(status==google.maps.GeocoderStatus.OK){
如果(结果[0]){//http://stackoverflow.com/questions/8082405/parsing-address-components-in-google-maps-upon-autocomplete-select
var address\u components=结果[0]。address\u components;
var组件={};
每个(地址、组件、函数(k、v1){
每个(v1.1)类型,函数(k2,v2){
组件[v2]=v1.long\u名称
});
})
var输出=“”;
var needAcomma=false;
if(components.route!=未定义){
输出+=组件.route;
needAcomma=真;
}
if(components.locality!=未定义){
如果(needAcomma){
输出+=',';
}
输出+=components.locality;
needAcomma=真;
}
if(组件.管理区\级别\ 1!=未定义){
如果(needAcomma){
输出+=',';
}
输出+=组件。管理区级别1;
needAcomma=真;
}else if(组件、管理区、级别2!=未定义){
如果(needAcomma){
输出+=',';
}
输出+=组件。管理区级别2;
needAcomma=真;
}else if(组件、管理区、级别3!=未定义){
如果(needAcomma){
输出+=',';
}
输出+=组件。行政区级别3;
needAcomma=真;
}
$(“#位置”).val(输出);
//打回电话
回调(输出);
}否则{
警报(“未找到结果”);
}
}否则{
警报('地理编码器因:'+状态而失败);
}
});
}

更改
reversegeocode
以获取
回调
参数(也称为
延续

封装所有需要等待
reversegeocode
完成的内容,将其放入一个到位的无名函数中

(请注意与您已经为
click
处理程序执行的操作的相似性。)

使用这种方法,您还可以自由地向回调添加参数,您可以使用回调直接传递数据

$('.addButton').click(function() { 
    reversegeocode(function(some_data) {
        var location = $("#location").val();//the value I need
        //...stuff...
    });
});

function reversegeocode(callback){
    //...stuff...
    geocoder.geocode({'latLng': latlng}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
          //...stuff...
        } else {
          alert('Geocoder failed due to: ' + status);
        }
        callback(some_data);
    });
}

看起来
reversegeocode
是一种异步方法,您需要与我们共享该方法,以了解可以做什么。无论如何,
reversegeocode
方法都需要提供某种回调功能,以便在完成时通知我们,谢谢您的响应。我把我的职能放在我的问题上了。它只是从谷歌那里得到地址并将结果粘贴到输入中。嗨,乔治-顺便说一下,很酷的胡子-我不确定我是否理解这个返回的部分。我实际上不需要它来返回任何东西,不需要返回任何东西就可以这样做吗?@crazysarah你可以,你当然不需要返回任何东西(然后你就不会得到(位置)参数。但是,我建议将执行反向地理编码的组件与在UI中实际设置它的过程分开。返回位置,并在一个
done
处理程序中设置
#locationsHolder
html,在另一个
done
处理程序中执行上述操作(如果这让您感到困惑,请阅读延迟文档)。您不应该在UI中使用html在函数之间进行通信-已经有了一种机制:参数和返回值。嗨,Arun,这非常有效,您是个天才!非常感谢!
function reversegeocode() {
  return $.Deferred(function(d) {
    //do stuff and when it succeeds
    d.resolve(location);
    //or if it fails
    d.reject("something went wrong");
  }).promise();
}
$('.addButton').click(function () {
    //pass a callback to reversegeocode which will get called once the geocoding is completed
    reversegeocode(function (location) {
        //the callback receives the location as a parameter
        $.post("<?php echo $this->webroot;?>locations/add", {
            location: location
        })
            .done(function (data) {
            $("#locationsHolder").html(data);
        });
    });
});

function reversegeocode(callback) {
    var lat = $('#lattitude').val();
    var lng = $('#longitude').val();
    var latlng = new google.maps.LatLng(lat, lng);
    geocoder.geocode({
        'latLng': latlng
    }, function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            if (results[0]) { //http://stackoverflow.com/questions/8082405/parsing-address-components-in-google-maps-upon-autocomplete-select
                var address_components = results[0].address_components;
                var components = {};
                jQuery.each(address_components, function (k, v1) {
                    jQuery.each(v1.types, function (k2, v2) {
                        components[v2] = v1.long_name
                    });
                })
                var output = '';
                var needAcomma = false;
                if (components.route != undefined) {
                    output += components.route;
                    needAcomma = true;
                }
                if (components.locality != undefined) {
                    if (needAcomma) {
                        output += ', ';
                    }
                    output += components.locality;
                    needAcomma = true;
                }
                if (components.administrative_area_level_1 != undefined) {
                    if (needAcomma) {
                        output += ', ';
                    }
                    output += components.administrative_area_level_1;
                    needAcomma = true;
                } else if (components.administrative_area_level_2 != undefined) {
                    if (needAcomma) {
                        output += ', ';
                    }
                    output += components.administrative_area_level_2;
                    needAcomma = true;
                } else if (components.administrative_area_level_3 != undefined) {
                    if (needAcomma) {
                        output += ', ';
                    }
                    output += components.administrative_area_level_3;
                    needAcomma = true;
                }
                $("#location").val(output);
                //call the callback
                callback(output);
            } else {
                alert('No results found');
            }
        } else {
            alert('Geocoder failed due to: ' + status);
        }
    });
}
$('.addButton').click(function() { 
    reversegeocode(function(some_data) {
        var location = $("#location").val();//the value I need
        //...stuff...
    });
});

function reversegeocode(callback){
    //...stuff...
    geocoder.geocode({'latLng': latlng}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
          //...stuff...
        } else {
          alert('Geocoder failed due to: ' + status);
        }
        callback(some_data);
    });
}