使用Deferreds获取位置并显示地图

时间:2012-11-25 15:58:05

标签: javascript

我试图用一个简单的例子来理解Revealing Module Pattern和jQuery Deferreds。

我希望能够做的是调用模块来获取用户的位置,然后调用成功后显示谷歌地图上的位置。

这两个操作本身都使用了一堆函数和回调对我来说没有问题,但我试图用更“馄饨”而不是“意大利面”的方式来做。

我发现,当延迟工作完美时,我的模块的公共属性不包含我在操作期间为获取位置而设置的值。

这是我的'geoModule'

var geoModule = function () {
    var lat;
    var lng;

    var init = function () {
    return $.Deferred(function (def) {
        getCurrentPositionDeferred({})
        .fail(function () { def.reject(); })
        .done(function (location) {
            lat = location.coords.latitude;
            lng = location.coords.longitude;
            logger.log("Got location : " + lat + " : " + lng);
            def.resolve();
        });
    }).promise();
    };

    var getCurrentPositionDeferred = function(options) {
    var deferred = $.Deferred();

    navigator.geolocation.getCurrentPosition(deferred.resolve, deferred.reject, options);

    return deferred.promise();
    };

    return { lat: lat, lng: lng, init: init };
}();

这是我的'mapModule'

var mapModule = function (mapId) {
    var mapElement = document.getElementById(mapId);
    var map;
    var initMap = function (lat, lng) {
    logger.log("init map: " +lat + " : " + lng);
    var myOptions = {
        zoom: 14,
        center: new google.maps.LatLng(lat, lng),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    map = new google.maps.Map(mapElement, myOptions);
    };


    return { initMap: initMap };
}('map');

当我把它们组合在一起时:

$.when(geoModule.init())
    .done(function () {
        logger.log("location done " + geoModule.lat + " : " + geoModule.lng);
        mapModule.initMap(geoModule.lat, geoModule.lng);
    });

geoModule.lat和geoModule.lng未定义,甚至认为在geoLocation中设置它们的代码已成功运行。

我在http://jsfiddle.net/faG4J/4/创建了一个显示日志输出的完整示例。我可能正在做一些非常愚蠢的事情,所以任何帮助都会非常受欢迎。

1 个答案:

答案 0 :(得分:1)

您设置的那些变量不是模块的属性 - 它们只是局部变量。您已将导出到模块对象,但一次没有设置它们。

然而,这根本不是你应该这样做的方式。不要对某些正在设置的对象的某些属性做出承诺,而是对这些值做出承诺。

由于只有一个函数的模块对我来说似乎没用,我在这里省略了它们:

function getPosition() {
    var deferred = $.Deferred();
    navigator.geolocation.getCurrentPosition(deferred.resolve, deferred.reject);
    // pipe the output of the deferred through this logging and transformation function
    return deferred.then(function (location) {
        var lat = location.coords.latitude;
        var lng = location.coords.longitude;
        logger.log("Got location : " + lat + " : " + lng);
        return {lat: lat, lng: lng};
    });
}

然后使用类似getPosition.done(createMap)的内容。