Javascript 链接承诺,或一个承诺触发另一个承诺
我正在构建一个天气应用程序,首先要获取用户的位置,然后请求获取天气 所以我有一个Javascript 链接承诺,或一个承诺触发另一个承诺,javascript,angularjs,promise,Javascript,Angularjs,Promise,我正在构建一个天气应用程序,首先要获取用户的位置,然后请求获取天气 所以我有一个GeolocationService和一个WeatherService。我的WeatherService当前正在调用Geolocation服务。如何使WeatherService在发出HTTP请求之前等待,直到获得GeolocationService的结果 app.factory('GeolocationService',function($q,$window,$rootScope){ return
GeolocationService
和一个WeatherService
。我的WeatherService
当前正在调用Geolocation
服务。如何使WeatherService
在发出HTTP请求之前等待,直到获得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;
});
}
};
});
应用程序工厂('GeolocationService',函数($q、$window、$rootScope){
返回{
getLatLon:function(){
var deferred=$q.deferred();
如果(!window.navigator){
$rootScope.$apply(函数(){
延迟。拒绝(新错误(“地理位置不可用”);
});
}否则{
$window.navigator.geolocation.getCurrentPosition(函数(位置){
$rootScope.$apply(函数(){
推迟。决议(立场);
});
},函数(错误){
$rootScope.$apply(函数(){
延迟。拒绝(错误);
});
});
}
回报。承诺;
}
};
});
app.factory(“WeatherService”,函数($q、$http、$rootScope、GeolocationService){
返回{
getWeather:function(){
天气变化;
var loc=new GeolocationService.getLatLon();
var lat=loc.lat | | 37.456820221774,
lon=loc.lon | |-122.201366838789;
var单位=“”;
var url='1〕http://api.openweathermap.org/data/2.5/forecast/daily?lat=“+lat+”&lon=“+lon+”&units=“+units+”&callback=JSON_callback”;
$http.jsonp(url)
.成功(功能(数据){
天气=数据;
回归天气;
})
.error(函数(err){
天气=错误;
返回错误;
});
}
};
});
你只需要在服务中使用承诺,然后将承诺链接起来。对于示例,我有一个user.company_id的用户,如果我想获得公司名称,我必须等待用户加载。这和你的处境是一样的 这是我的服务:
angular.module('UserService', [])
.factory('UserService', function($q , $http, $rootScope,$timeout) {
var currentUserPromise = null;
var currentCompanyPromise = null;
return {
getCurrentUser: function() {
if (currentUserPromise === null) {
var config = {};
config.cache = true;
config.method = "GET";
config.url = "users/get_current_user";
currentUserPromise = $http(config)
.then(function(response) {
if (typeof response.data === 'object') {
return response.data.user;
} else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
return currentUserPromise;
},
getCurrentCompany: function(company_id) {
if (currentCompanyPromise === null){
var config = {};
var company = {};
company.id = company_id;
config.cache = true;
config.method = "GET";
config.url = "/companies/show";
config.params = company;
currentCompanyPromise = $http(config)
.then(function(response) {
if (typeof response.data === 'object') {
return response.data.company;
} else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
return currentCompanyPromise;
}
};
});
在我的控制器中,我的用户是这样的:
控制器:
var promiseCurrentUser = UserService.getCurrentUser();
promiseCurrentUser.then(function(user) {
$scope.currentUser = user;
UserService.getCurrentCompany(user.company_id).then(function(company){
$scope.companyName = company.name;
});
});
承诺的酷之处在于它是一次性的
我希望这会对您有所帮助。您只需要在服务中使用承诺,然后将承诺链接起来。对于示例,我有一个user.company_id的用户,如果我想获得公司名称,我必须等待用户加载。这和你的处境是一样的 这是我的服务:
angular.module('UserService', [])
.factory('UserService', function($q , $http, $rootScope,$timeout) {
var currentUserPromise = null;
var currentCompanyPromise = null;
return {
getCurrentUser: function() {
if (currentUserPromise === null) {
var config = {};
config.cache = true;
config.method = "GET";
config.url = "users/get_current_user";
currentUserPromise = $http(config)
.then(function(response) {
if (typeof response.data === 'object') {
return response.data.user;
} else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
return currentUserPromise;
},
getCurrentCompany: function(company_id) {
if (currentCompanyPromise === null){
var config = {};
var company = {};
company.id = company_id;
config.cache = true;
config.method = "GET";
config.url = "/companies/show";
config.params = company;
currentCompanyPromise = $http(config)
.then(function(response) {
if (typeof response.data === 'object') {
return response.data.company;
} else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
return currentCompanyPromise;
}
};
});
在我的控制器中,我的用户是这样的:
控制器:
var promiseCurrentUser = UserService.getCurrentUser();
promiseCurrentUser.then(function(user) {
$scope.currentUser = user;
UserService.getCurrentCompany(user.company_id).then(function(company){
$scope.companyName = company.name;
});
});
承诺的酷之处在于它是一次性的
我希望这会对您有所帮助。您只需要在服务中使用承诺,然后将承诺链接起来。对于示例,我有一个user.company_id的用户,如果我想获得公司名称,我必须等待用户加载。这和你的处境是一样的 这是我的服务:
angular.module('UserService', [])
.factory('UserService', function($q , $http, $rootScope,$timeout) {
var currentUserPromise = null;
var currentCompanyPromise = null;
return {
getCurrentUser: function() {
if (currentUserPromise === null) {
var config = {};
config.cache = true;
config.method = "GET";
config.url = "users/get_current_user";
currentUserPromise = $http(config)
.then(function(response) {
if (typeof response.data === 'object') {
return response.data.user;
} else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
return currentUserPromise;
},
getCurrentCompany: function(company_id) {
if (currentCompanyPromise === null){
var config = {};
var company = {};
company.id = company_id;
config.cache = true;
config.method = "GET";
config.url = "/companies/show";
config.params = company;
currentCompanyPromise = $http(config)
.then(function(response) {
if (typeof response.data === 'object') {
return response.data.company;
} else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
return currentCompanyPromise;
}
};
});
在我的控制器中,我的用户是这样的:
控制器:
var promiseCurrentUser = UserService.getCurrentUser();
promiseCurrentUser.then(function(user) {
$scope.currentUser = user;
UserService.getCurrentCompany(user.company_id).then(function(company){
$scope.companyName = company.name;
});
});
承诺的酷之处在于它是一次性的
我希望这会对您有所帮助。您只需要在服务中使用承诺,然后将承诺链接起来。对于示例,我有一个user.company_id的用户,如果我想获得公司名称,我必须等待用户加载。这和你的处境是一样的 这是我的服务:
angular.module('UserService', [])
.factory('UserService', function($q , $http, $rootScope,$timeout) {
var currentUserPromise = null;
var currentCompanyPromise = null;
return {
getCurrentUser: function() {
if (currentUserPromise === null) {
var config = {};
config.cache = true;
config.method = "GET";
config.url = "users/get_current_user";
currentUserPromise = $http(config)
.then(function(response) {
if (typeof response.data === 'object') {
return response.data.user;
} else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
return currentUserPromise;
},
getCurrentCompany: function(company_id) {
if (currentCompanyPromise === null){
var config = {};
var company = {};
company.id = company_id;
config.cache = true;
config.method = "GET";
config.url = "/companies/show";
config.params = company;
currentCompanyPromise = $http(config)
.then(function(response) {
if (typeof response.data === 'object') {
return response.data.company;
} else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
return currentCompanyPromise;
}
};
});
在我的控制器中,我的用户是这样的:
控制器:
var promiseCurrentUser = UserService.getCurrentUser();
promiseCurrentUser.then(function(user) {
$scope.currentUser = user;
UserService.getCurrentCompany(user.company_id).then(function(company){
$scope.companyName = company.name;
});
});
承诺的酷之处在于它是一次性的
我希望这将对您有所帮助。您的
GeolocationService
功能getLatLon
正在返回一个承诺。无需使用new
运算符调用它
您的getWeather
函数应该符合以下内容:
app.factory(“WeatherService”,函数($q、$http、$rootScope、GeolocationService){
返回{
getWeather:function(){
天气变化;
返回GeolocationService.getLatLon()。然后(
功能(loc){
var lat=loc.lat | | 37.456820221774,
lon=loc.lon | |-122.201366838789;
var单位=“”;
var url='1〕http://api.openweathermap.org/data/2.5/forecast/daily?lat=“+lat+”&lon=“+lon+”&units=“+units+”&callback=JSON_callback”;
返回$http.jsonp(url)
.成功(功能(数据){
天气=数据;
回归天气;
})
.error(函数(err){
天气=错误;
返回错误;
});
});
}
}
}
在这里,我们首先调用GeolocationService.getLatLon()
以获得承诺。然后我们将处理作为一个链链接到它。success函数将获得位置
您使用Heredeferred.resolve(position);
解决它
此外,您不需要将解析
和拒绝
包装在$apply
中。因此,您的地理定位服务
可以简化为:
if(!window.navigator){
延迟。拒绝(新错误(“地理位置不可用”);
}否则{
$window.navigator.geolocation.getCurrentPosition(函数(位置){
推迟。决议(立场);
},功能(er