Angular-等待异步任务完成

时间:2016-06-28 20:37:48

标签: angularjs asynchronous promise

背景:

目前我有一个函数可以从数据库中返回前5位客户。但是,返回的对象仅包含{userId,visitCount}。为了检索用户名,我需要进行另一次API调用以获取基于userId的用户配置文件。最终对象($ scope.topFiveCustomer)将包含以下信息{userId,visitCount,name}。

问题:

在我检索用户名后,当我使用console.log打印$ scope.topFiveCustomers [0]时,此对象只包含{userId,visitCount}。我想知道在我做其他事情之前有没有办法等待检索名称(以下代码)?

_.each($scope.topFiveCustomers, function(customer) {
    CustomerService.getCustomer(customer.uuid)
        .then(function(response) {
            customer['name'] = response.data.name;
        })
});

当前代码:

$scope.getTopFive = function() {
    DashboardService.getCustomerList($scope.topCustomerTime.value)
        .then(function(customerList) {
            $scope.topFiveCustomers = _.sortBy(customerList, 'visitCount').reverse().slice(0,5);

            _.each($scope.topFiveCustomers, function(customer) {
                CustomerService.getCustomer(customer.uuid)
                    .then(function(response) {
                        customer['name'] = response.data.name;
                    })
            });

            console.log($scope.topFiveCustomers);
            //name: test
            //uuid: 1234
            //visitCount: 5 

           console.log($scope.topFiveCustomers[0]);
           //uuid: 1234
           //visitCount: 5

    });

};

我尝试使用$ q解决此问题:

function getCustomerName(){
    var deferred = $q.defer();

    _.each($scope.topFiveCustomers, function(customer) {
        CustomerService.getCustomer(customer.uuid)
            .then(function(response) {
                customer['name'] = response.data.name;
            })
    });

    deferred.resolve();

    return deferred.promise;
}


$scope.getTopFive = function() {
    DashboardService.getCustomerList($scope.topCustomerTime.value)
        .then(function(customerList) {
            $scope.topFiveCustomers = _.sortBy(customerList, 'visitCount').reverse().slice(0,5);

            getCustomerName()
                .then(function() {
                    new Chartist.Bar('#topCustomer', {
                      labels: [$scope.topFiveCustomers[0].uuid],
                      series: [$scope.topFiveCustomers[0].visitCount]
                    }, {
                      distributeSeries: true,
                      reverseData: true,
                      horizontalBars: true,
                      width: 250,
                      height: 250
                    });
                });                           
        });
};

1 个答案:

答案 0 :(得分:0)

您必须使用$q.all功能的用户,该功能将等待所有五个客户数据被检索。

<强>代码

function getCustomerName() {
    var promises = [];
    _.each($scope.topFiveCustomers, function(customer) {
        //creating a promise array 
        promises.push(CustomerService.getCustomer(customer.uuid)
            .then(function(response) {
                customer['name'] = response.data.name;
            }))
    });
    return $q.all(promises); //returning combined 5 promises array.
};


$scope.getTopFive = function() {
    DashboardService.getCustomerList($scope.topCustomerTime.value)
      .then(function(customerList) {
      $scope.topFiveCustomers = _.sortBy(customerList, 'visitCount').reverse().slice(0, 5);

      getCustomerName() //will wait till all promises get resolved.
        .then(function(response) {
        angular.forEach($scope.topFiveCustomers, function(customer) {
          new Chartist.Bar('#topCustomer', {
            labels: [customer.uuid],
            series: [customer.visitCount]
          }, {
            distributeSeries: true,
            reverseData: true,
            horizontalBars: true,
            width: 250,
            height: 250
          });
        });
      });
    });
};