Angular Service/Controller 没有返回承诺?

Angular Service/Controller not returning promise?

所以我终于让我的应用程序运行到它为 JSON 请求获得正确 URL 的地方。但是现在我无法让它与 URL 一起工作。

我知道该服务正在从 Google 地图 API 返回承诺,我可能不应该这样做,但如果我不这样做,我会收到 "Weather.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;
    });
};

您不应在您的 getWeather 服务功能中使用 .success,因为它不允许您 return 任何类型的 data。因为回调函数不能 returning 任何东西 Read Here about callback & promise。所以你应该使用 promise 方法来处理异步请求,基本上你可以 return 从 promise 函数到调用该函数的消费者函数的数据。实际上,当 ajax 完成时,它确实调用了消费者 .then 函数。

您只需在 getWeather 函数中使用 .then 函数,然后在解析该异步调用时它将调用 getWeatherData 函数,该函数将再次 return 是一个承诺。因此,当它得到解决时,它会调用 getWeatherData 的 .then 函数,当它 return 的数据来自它时,那时 Weather.getWeather(city).then 函数将被调用。这整件事只不过是你在承诺链中实现的。一个函数等待其他函数,一旦底层承诺得到解决,它就会调用其 .then 函数。

Read here about 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 函数中创建额外的 promise,因为您可以在那里调用 $http 的 promise。

代码

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;
    });
}

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);
};