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函数将获得
位置
您使用Here
deferred.resolve(position);
解决它

此外,您不需要将
解析
拒绝
包装在
$apply
中。因此,您的
地理定位服务
可以简化为:

if(!window.navigator){
延迟。拒绝(新错误(“地理位置不可用”);
}否则{
$window.navigator.geolocation.getCurrentPosition(函数(位置){
推迟。决议(立场);
},功能(er