我正在构建一个天气应用程序,我首先要获取用户位置,然后请求获取天气 .
所以我有 GeolocationService
和 WeatherService
. 我的 WeatherService
目前正在调用 Geolocation
服务 . 在发出HTTP请求之前,如何让 WeatherService
等到 GeolocationService
的结果?
app.factory('GeolocationService',function($q,$window,$rootScope){
return {
getLatLon: function(){
var deferred = $q.defer();
if(!window.navigator){
$rootScope.$apply(function(){
deferred.reject(new Error("Geolocation not available"));
});
} else {
$window.navigator.geolocation.getCurrentPosition(function(position){
$rootScope.$apply(function(){
deferred.resolve(position);
});
}, function(error){
$rootScope.$apply(function(){
deferred.reject(error);
});
});
}
return deferred.promise;
}
};
});
app.factory("WeatherService", function ($q,$http,$rootScope, GeolocationService) {
return {
getWeather: function(){
var weather;
var loc = new GeolocationService.getLatLon();
var lat= loc.lat || 37.4568202221774,
lon= loc.lon || -122.201366838789 ;
var units = '';
var url = 'http://api.openweathermap.org/data/2.5/forecast/daily?lat='+lat+'&lon='+lon+'&units='+units+'&callback=JSON_CALLBACK';
$http.jsonp(url)
.success(function(data) {
weather=data;
return weather;
})
.error(function(err){
weather=err;
return err;
});
}
};
});
2 回答
您只需要在服务中使用承诺,然后将承诺链接起来 . 对于示例,我有一个user.company_id的用户,如果我想得到公司的名称,我必须等待用户加载 . 它和你的情况一样 .
这是我的服务:
在我的控制器中,我这样使用:
控制器:
承诺的真正好处在于它只能解决一次 .
我希望这能帮到您 .
你的
GeolocationService
的函数getLatLon
正在返回一个承诺 . 无需使用new
运算符调用它 .你的
getWeather
函数看起来应该是这样的:在这里,我们首先调用
GeolocationService.getLatLon()
来获得一个承诺 . 然后我们将我们的处理链接到它 . 成功函数将使用deferred.resolve(position);
来解析position
.此外,您不需要在
$apply
中包装resolve
和reject
. 因此,您的GeoLocationService
可以简化为: