Angular服务/控制器没有返回承诺

Angular Service/Controller not returning promise?

本文关键字:返回 承诺 控制器 服务 Angular      更新时间:2023-09-26

所以我终于让我的应用程序工作到它得到JSON请求的正确URL的地方。然而,现在我不能得到它的工作与该URL。

我知道服务正在从Google Maps API返回承诺,我可能不应该这样做,但是如果我把它去掉,我得到一个"天气"。getWeather is undefined"错误。我不知道为什么。

我怎样才能使它正确工作。谢谢你的帮助。

weatherService.getWeather = function(city)  {

        var coordsUrl = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + city;

        return $http.get(coordsUrl)
            .success(function(data) {
                var coords = data.results[0].geometry.location.lat + ',' + data.results[0].geometry.location.lng;
            return getWeatherData(coords);  
        }); 
function getWeatherData(coords)  {
            var deferred = $q.defer(),
            apiKey = 'cbbdddc644184a1d20ffc4a0e439650d',
            weatherUrl = 'https://api.forecast.io/forecast/' + apiKey + '/' + coords + '?callback=JSON_CALLBACK';

            $http.jsonp(weatherUrl)
                .success(function(data) {
                    deferred.resolve(data);
                }).error(function(err) {
                    deferred.reject(err);
                });
            console.log(weatherUrl);
            return deferred.promise;
        }        
    };

控制器:

vm.fetchWeather = function(city) {
    Weather.getWeather(city)
        .then(function(data) {
            console.log(data);
            vm.place = data;
    });
};

您不应该在不允许您返回任何类型的datagetWeather服务函数中使用.success。因为回调函数不能返回任何东西阅读这里关于回调&承诺。你应该使用promise recipe去处理异步请求,基本上你可以从promise函数返回数据给调用那个函数的消费者函数。实际上,当ajax完成时,它会调用消费者.then函数。

你需要简单地在你的getWeather函数中使用.then函数,然后在解析异步调用时,它将调用getWeatherData函数,这将再次返回一个承诺。因此,当它被解析时,当它返回数据时,它调用getWeatherData的。then函数,此时Weather.getWeather(city).then函数将被调用。这一切都是你在承诺链中实现的。一个函数等待其他函数,一旦底层承诺被解决,它调用它的.then函数。

阅读这里关于Promise

return $http.get(coordsUrl)
 .then(function(resp) {
    var data = resp.data
    var coords = data.results[0].geometry.location.lat + ',' + data.results[0].geometry.location.lng;
    return getWeatherData(coords);  
}); 

也不需要在getWeatherData函数中创建额外的承诺,因为您可以在那里利用$http调用的承诺。

function getWeatherData(coords)  {
    var apiKey = 'cbbdddc644184a1d20ffc4a0e439650d',
    weatherUrl = 'https://api.forecast.io/forecast/' + apiKey + '/' + coords + '?callback=JSON_CALLBACK';
    return $http.jsonp(weatherUrl)
    .then(function(resp) {
       var data = resp.data;
       //you could play with data here before returning it.
       return data;
    },function(error) {
       return error;
    });
}

Edit by Roamer-1888

或者,修改getWeatherData()以接受data并为自己计算coords。然后,流控制语句将简化为return $http.get(coordsUrl).then(getWeatherData);

weatherService.getWeather = function(city) {
    var coordsUrl = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + city;
    function getWeatherData(data) {
        var apiKey = 'cbbdddc644184a1d20ffc4a0e439650d',
            coords = data.results[0].geometry.location.lat + ',' + data.results[0].geometry.location.lng,
            weatherUrl = 'https://api.forecast.io/forecast/' + apiKey + '/' + coords + '?callback=JSON_CALLBACK';
        return $http.jsonp(weatherUrl);
    }
    return $http.get(coordsUrl).then(getWeatherData);
};