我试图用一个简单的例子来理解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/创建了一个显示日志输出的完整示例。我可能正在做一些非常愚蠢的事情,所以任何帮助都会非常受欢迎。
答案 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)
的内容。