如何从Javascript中的匿名函数获取结果?

时间:2014-02-05 10:41:18

标签: javascript jquery google-maps-api-3

我正在使用一个简单的脚本来对地址进行地理编码。

var geocoder;
var departure;
var arrival;

function initialize() {
    geocoder = new google.maps.Geocoder();
}

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

function geocode(options) {
    var address = options.address.val() || null;
    var result = {};
    if (address) {
        geocoder.geocode( { 'address': address }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                result.lat = results[0].geometry.location.lat();
                result.lng = results[0].geometry.location.lng();
            } else {
                result.lat = null;
                result.lng = null;
            }
        });
    }
}

function geocode_all() {
    departure = geocode({
        address: $('#departure')
    });
    //console.log(departure);

    arrival = geocode({
        address: $('#arrival')
    });
    //console.log(arrival);
}

我希望我的离开变量和我的到达变量成为对象的最终纬度和经度。

我应该如何处理,因为我的结果变量超出了范围?

谢谢!

1 个答案:

答案 0 :(得分:1)

问题不在于函数是匿名的,而不是范围;问题是Google地理位置API是异步。您的geocode函数无法返回其结果;相反,就像Google的功能一样,它必须接受一个回调,当结果已知时,它会回调结果以后。 (或者它可以通过“承诺”模式间接使用回调,但基本概念是相同的。)

所以,使用回调:

function geocode(options, callback) {
    //                    ^--- Accept the callback
    var address = options.address.val() || null;
    var result = {};
    if (address) {
        geocoder.geocode( { 'address': address }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                result.lat = results[0].geometry.location.lat();
                result.lng = results[0].geometry.location.lng();
            } else {
                result.lat = null;
                result.lng = null;
            }
            callback(result); // <== Call it
        });
    }
}

// usage
geocode({/*...*/}, function(result) {
    // This gets called later, asynchronously, with the result
});

或使用jQuery Deferred / Promise

function geocode(options) {
    var d = new $.Deferred(); // <== Create the deferred
    var address = options.address.val() || null;
    var result = {};
    if (address) {
        geocoder.geocode( { 'address': address }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                result.lat = results[0].geometry.location.lat();
                result.lng = results[0].geometry.location.lng();
            } else {
                result.lat = null;
                result.lng = null;
            }
            // Resolve the Deferred using your result
            d.resolve(result);
        });
    }

    // Return the Promise for the Deferred
    return d.promise();
}

// Usage
geocode({/*....*/}).done(function(result) {
    // This gets called later, asynchronously, with the result
});