以角度来回归链式承诺的“最后”价值

时间:2015-10-28 18:52:01

标签: javascript angularjs promise angular-promise angularjs-factory

我正在尝试进行一些地理定位,并根据坐标调用返回一些数据的RESTful API。然后我想解析这些数据,最后返回它 我对angular.js和promises相当新,因此这段代码是我通过互联网看到的混合物:D

我已经完成了所有工作,但我错过了最后一步:将处理后的结果数组(“allSpots”)返回给原始调用者。我在这里缺少什么?

.factory('wifiSpotFactory', function (WifinderModel, $q, $http) {

            function onGeolocationSuccess(position) {

            var url = 'http://localhost:34915/api/spots?latitude=' + position.coords.longitude + '&longitude=' + position.coords.latitude;

            $http.get(url).then(function (response) {

                var allSpots = [], data = response.data;
                for (var i = 0; i < data.length; i++) {
                    var newSpot = new WifinderModel.wifiSpot(data[i].id, data[i].name, data[i].password, data[i].address);
                    allSpots.push(newSpot);
                }

                return allSpots;

            }, function (error) {
                console.log(error);
            });

        };

            var wifiSpotFactory = {
                loadNearSpots: function() {
                var geo_options = {
                    enableHighAccuracy: true,
                    maximumAge: 50000,
                    timeout: 30000
                };

                var deferred = $q.defer();

                navigator.geolocation.getCurrentPosition(deferred.resolve, deferred.reject, geo_options);

                return deferred.promise
                        .then(onGeolocationSuccess)
                        .then(function(allSpots) { return allSpots; });
            }
            };
            return wifiSpotFactory;
            } )

然后在控制器中,如何检索承诺的值?

.controller('wifiListController', [
                '$scope', 'wifiSpotFactory', function ($scope, wifiSpotFactory) {
                    $scope.spots = wifiSpotFactory.loadNearSpots();
               }
])

2 个答案:

答案 0 :(得分:1)

Callback没有能力返回数据,你应该真正使用promise模式,它有能力从promise返回数据。您onGeolocationSuccess正在使用似乎return data的回调模式,但实际上它并没有。

您可以通过从onGeolocationSuccess方法返回promise来解决问题,因为您需要返回已经返回promise对象的$http.get对象。在该函数的.then中,您将获得从API返回的data。从.then函数中,您可以返回data,以帮助您关注promise pattern

<强>代码

.factory('wifiSpotFactory', function(WifinderModel, $q, $http) {

  function onGeolocationSuccess(position) {
    var url = 'http://localhost:34915/api/spots?latitude=' + position.coords.longitude + '&longitude=' + position.coords.latitude;

    return $http.get(url).
    then(function(response) {
      var allSpots = [],
          data = response.data;
      for (var i = 0; i < data.length; i++) {
        var newSpot = new WifinderModel.wifiSpot(data[i].id, data[i].name, data[i].password, data[i].address);
        allSpots.push(newSpot);
      }
      return allSpots;

    }, function(error) {
      console.log(error)
    });
  };

  var wifiSpotFactory = {
    loadNearSpots: function() {
      //..other code as is..to make solution cleaner removed that part.
      //return promise to follow promise chain
      return deferred.promise
      .then(onGeolocationSuccess)
      .then(function(allSpots) {
        return allSpots;
      });
    }
  };
  return wifiSpotFactory;
})

<强>控制器

.controller('wifiListController', ['$scope', 'wifiSpotFactory', 
   function ($scope, wifiSpotFactory) {
       wifiSpotFactory.loadNearSpots().then(function(data){
           $scope.spots = data; //data will be available inside `.then` which promise resolve/reject
       });
   }
])

答案 1 :(得分:0)

返回链接的承诺:

function onGeolocationSuccess(position) {
  var url = 'http://localhost:34915/api/spots?latitude=' + position.coords.longitude + '&longitude=' + position.coords.latitude;

  return $http.get(url).success(function(data, status, headers, config) {
    var allSpots = [];
    for (var i = 0; i < data.length; i++) {
      var newSpot = new WifinderModel.wifiSpot(data[i].id, data[i].name, data[i].password, data[i].address);
      allSpots.push(newSpot);
    }

    return allSpots;

  }).error(function(data, status, headers, config) {});
};

然后呼叫可以是:

deferred.promise
.then(onGeolocationSuccess)
.then(function(allSpots) { ... });