1

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

我想要做的是调用一个模块来获取用户的位置,以及该调用何时以及是否成功在谷歌地图上显示该位置。

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

我发现虽然 deferred 运行良好,但我的模块的公共属性不包含我在操作期间设置的值以获取位置。

这是我的“地理模块”

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/创建了一个完整的示例,显示了日志输出。我可能正在做一些非常愚蠢的事情,所以任何帮助将不胜感激。

4

1 回答 1

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).

于 2012-11-25T18:32:59.930 回答