Angular Service/Controller没有回复承诺?

Dev*_*ero 1 javascript promise angularjs angularjs-http angular-promise

所以我终于让我的应用程序工作到它获得JSON请求的正确URL.但是现在我无法使用该URL.

我知道该服务正在从Google Maps 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;
        }        

    };
Run Code Online (Sandbox Code Playgroud)

控制器:

vm.fetchWeather = function(city) {

    Weather.getWeather(city)
        .then(function(data) {
            console.log(data);
            vm.place = data;
    });
};
Run Code Online (Sandbox Code Playgroud)

Pan*_*kar 5

您不应该.success在您的getWeather服务功能中使用不允许您返回任何类型的服务功能data.因为回调函数不能返回任何关于回调和承诺的Read Here.所以你应该去处理异步请求的promise配方,基本上你可以将promise函数中的数据返回到调用该函数的consumer函数.实际上.then,当ajax完成时,它会调用消费者函数.

你只需要.then在你的getWeather函数中使用函数,然后在解析该异步调用时它将调用该getWeatherData函数,它将再次返回一个promise.因此,当它得到解决它.然后调用函数getWeatherData时,它从它返回的数据,当时Weather.getWeather(city).then功能会得到调用.这一切都只是你在诺言链中实现的.一个函数等待其他函数,一旦底层的promise得到解决,它就会调用它的.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);  
}); 
Run Code Online (Sandbox Code Playgroud)

此外,不需要在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;
    });
}
Run Code Online (Sandbox Code Playgroud)

由Roamer-1888编辑

或者,修改getWeatherData()为接受datacoords自行计算.然后,流控制语句将简化为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);
};
Run Code Online (Sandbox Code Playgroud)