【问题标题】:Angular- wait for async task to completeAngular-等待异步任务完成
【发布时间】:2016-06-29 04:48:31
【问题描述】:

背景:

目前我有一个函数可以从数据库中返回前 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
                    });
                });                           
        });
};

【问题讨论】:

  • 你可以简单地将$http的值作为promise返回:$http.get().then(function () { return $http.get().then(); });跨度>

标签: angularjs asynchronous promise


【解决方案1】:

您必须使用$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
          });
        });
      });
    });
};

【讨论】:

  • 感谢您的解决方案!