2017-05-04 14 views
2

以下の簡単な例では、最初のメソッド呼び出し(getProducts)が完了した後に呼び出す必要があるメソッド呼び出し(getMoreProducts)があります。コントローラ複数の同期ネストされたサービスコールを作成する

私はangularjs(そしてかなりJSに新しい)としてこれを達成する別の方法があるかどうかを確認したいと思います。私の懸念は、別のメソッドをgetMoreProductsの後に呼び出す必要がある場合、コードは3つのレベルの深さになるということです。

.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

参照[約束のコールバックをネスト解除する方法](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

編集:ところで

、私はそれだけで、デフォルトのplunkerテンプレートだ、コントローラおよびサービスを作成するためのこのスタイルをrecommmendません。

がこの約束が反対を助けることになっているかを正確にある、Y021Y022Y031

1

OPにネストされた約束で使用されているアンチパターンは、「コールバック地獄」の形式で参照してください。約束は互いの結果に依存しない場合は

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) { ... }); 

:次の呼び出しは約束は、直列に彼らは深い1つのレベルにすぎない、このようにチェーンする必要があり、以前の呼び出しに依存

(この場合のように)、それらを並列に実行することができ、これは$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; 
}); 
関連する問題