2017-05-04 92 views
2

在下面的简单的例子,我有一个需要第一个方法调用(getProducts)已完成之后调用的方法调用(getMoreProducts)。控制器使同步多重嵌套服务呼叫

由于我是新来angularjs(和相当新的JS),我想确认是否有实现这一目标的另一种方式。我担心的是,如果另一种方法需要getMoreProducts之后调用,代码后会有三个层次深,等等。

.controller('ProductController',function(ProductService, $scope){ 
    $scope.products = []; 
    $scope.moreProducts = []; 

    ProductService.getProducts().then(function(res){ 
    $scope.products = res.data; 

    ProductService.getMoreProducts().then(function(res){ 
     $scope.moreProducts = res.data; 
    }); 
    }); 

在这个例子中,假设ProductService方法是简单地调用调用HTTP GET调用。

+0

参见[如何UNNEST承诺回调](http://stackoverflow.com/a/22000931/1048572 ) – Bergi

+1

这些调用的*不*同步,他们是连续的。 – Bergi

回答

0

是的,你可以利用的承诺链接。如果返回内的另一个诺言,你可以避免讨厌的嵌套:

var app = angular.module('plunker', []); 


// Before 
app.controller('MainCtrl', function($scope, ProductService) { 
    $scope.name = 'World'; 

    $scope.products = []; 
    $scope.moreProducts = []; 

    ProductService.getProducts().then(function(res){ 
    $scope.products = res.data; 

    ProductService.getMoreProducts().then(function(res){ 
     $scope.moreProducts = res.data; 
    }); 
    }); 
}); 

// After with promise chaining 
app.controller('MainCtrl', function($scope, ProductService) { 
    $scope.name = 'World'; 

    $scope.products = []; 
    $scope.moreProducts = []; 

    ProductService.getProducts().then(function(res){ 
    $scope.products = res.data; 
    return ProductService.getMoreProducts() 
    }) 
    .then(function(res){ 
     $scope.moreProducts = res.data; 
    }); 
}); 


app.service('ProductService', function($timeout){ 
    this.getProducts = function() { 
    return $timeout(function(){ 
     return { 
     data: [{name: 'Widget', color: 'blue'}] 
     } 
    }, 500) 
    } 

    this.getMoreProducts = function() { 
    return $timeout(function(){ 
     return { 
     data: [{name: 'Widget', color: 'green'}, {name: 'Widget', color: 'red'}] 
     } 
    }, 1000) 
    } 
}) 

取决于对getProductsgetMoreProducts通话的要求,就可以使用,而不是把不同的功能参数。

http://plnkr.co/edit/K4LPKWSD06QnwbRk8k0B?p=preview

编辑:

顺便说一句,我不recommmend创建控制器和服务的这种风格,它只是默认plunker模板。

Y021Y022Y031

1

是嵌套承诺用在OP的反模式是“回调地狱”的一种形式,这也正是诺言应该什么来帮助对抗。

当下次呼叫依赖于以前的通话,承诺应当在一系列链接,这样,他们是不超过1平深:

ProductService.getProducts().then(function (productsRes) { 
    $scope.products = productsRes.data; 
    return ProductService.getMoreProducts(); 
    }) 
    .then(function (moreProductsRes) { 
     $scope.moreProducts = moreProductsRes.data; 
    return ProductService.getEvenMoreProducts(); 
    }) 
    .then(function (evenMoreProductsRes) { ... }); 

当承诺不依赖于彼此的结果(如在这种情况下),它们可以被并行地执行,而这正是$q.all为:

$q.all([ProductService.getProducts(), ProductService.getMoreProducts()]) 
.then(function (responses) { 
    var productsRes = responses[0]; 
    var moreProductsRes = responses[1]; 
    $scope.products = productsRes.data; 
    $scope.moreProducts = moreProductsRes.data; 
});