在组合多个API调用和处理之后从工厂方法返回promise

时间:2016-11-17 12:37:54

标签: javascript angularjs promise

我一直在使用简单的http方法返回的承诺。但我需要首先链接多个API调用并处理数据并返回该数据。问题是我当前实现的问题是工厂没有返回承诺,因此不等待数据并执行控制器的下一行。

app.factory('mytestService', ['$http', function($http){
    getSomeDataById: function(id){
    var userAllProjects = [];
     var myHelperService = this.getSecondData;
     this.getFirstData(id).then(function(response){ // first api call
         var idObjectValue = response['result'][0]['id'];
         myHelperService(idObjectValue).then(function(response){ //second api call
           userAllProjects= response['projectList']
        });
   });
    return userAllProjects
   }
]);

我现在在控制器中:

$scope.allProjects = mytestService.getSomeDataById(1234);
console.log($scope.allProjects);

控制台打印未定义。我知道这是因为,它不会等待服务完成并且排除下一行。

我是角度承诺的新手,所以不知道如何处理。有人可以帮我这里。  如果您需要任何进一步的信息,请与我们联系。

3 个答案:

答案 0 :(得分:3)

介绍Promise Chaining时,通常首选创建新的deferred

getSomeDataById: function(id){
    var userAllProjects = [];
    var myHelperService = this.getSecondData;

    // returning promise rather than creating a new one, 
    // to prevent unresolved promise if one of the calls in the chain gets rejected
    return this.getFirstData(id).then(function(response){ // first api call
        var idObjectValue = response['result'][0]['id'];
        return myHelperService(idObjectValue);  //second api call
        // instead of writing .then here, 
        // it can be moved to the outer layer for easy reading

    }).then(function(response){
        userAllProjects = response['projectList'];
        // return something you need to use in .then of getSomeDataById() here
    });
});

答案 1 :(得分:0)

您可以在控制器内使用then

<强>工厂

app.factory('mytestService', ['$http', function($http) {
    getSomeDataById: function(id) {
        var myHelperService = this.getSecondData;
        return this.getFirstData(id);
    },
    secondApiCall : function(idObjectValue){
      return myHelperService(idObjectValue);
    }
}]);

<强>控制器

mytestService.getSomeDataById(1234).then(function(response){
  mytestService.secondApiCall(response['result'][0]['id']).then(function(response2){
    $scope.allProjects = response.data;
  })
});

答案 2 :(得分:-1)

请尝试以下代码。

getSomeDataById: function(id){
  var userAllProjects = $q.defer();
  var myHelperService = this.getSecondData;
  this.getFirstData(id).then(function(response){ // first api call
     var idObjectValue = response['result'][0]['id'];
     myHelperService(idObjectValue).then(function(response){ //second api call
       userAllProjects.resolve(response['projectList'])
    });
  });
  return userAllProjects.promise;
}

这个想法是,首先创建一个延迟对象,然后返回promise。当数据可用时,您将解析延迟对象,并且数据将在您的控制器中可用。

注意:您需要在$q

上添加依赖项

参考:https://docs.angularjs.org/api/ng/service/$q