2016-07-07 9 views
0

私はこの作業を何回試みたのかを数えなくなりました。私はそれを得ていない。角度apiがループ/関数内で特定の順序で呼び出す

のは、私は、次のAPI呼び出しを持っているふりをしてみましょう:

API /顧客(CUST)

API /オーダー(受注)

API /製品(商品コード)関連

API /を(relatedid)

すべてのことが言われると、私は配列とサブ配列(以下で説明する)としてすべてのデータを含む単一のオブジェクトが必要です。

私はapi/customerのapi呼び出しを行う必要があります。リターンは、オブジェクトの配列としての顧客の以前の注文であることになります。彼らは3つの注文をしたふりをしよう。

各オブジェクトの内部にはさまざまなキー:値のペアがあり、それ自体がproductidという配列の「products」と呼ばれるものを含みます。今

私はすべての製品ID番号を通って、それぞれ1とループは、呼び出す必要があります:

API /製品(商品コード)

これも各製品のを見つけるために、ループスルーしなければならないの配列を返します。 "relatedid"値。その後、各顧客のそれぞれのために、各製品に関連するすべての製品を返す

API /関連(relatedid)

は、次に上記ループ内で私は再びでAPIを連絡する必要があります。

1つの顧客が3つの注文を持ち、各注文に5つの製品があり、各製品に10の関連製品がある可能性があります。

どのようにこのようなコードを作成し、上から下への各API呼び出しが完了する前に完了していることを確認しますか?あなたはそれを複数のループの中でどうやってやりますか?

すべてを言って、私はこのような何かを期待しています行われます。

{ 
customerid: 10 
previousOrderids: {10, 11, 12} 
orderedProducts: {10: {101, 102, 103, 104}, 11:{201, 202, 203, 204}, 12:{301, 302} 
relatedProducts: {101: {5, 6, 7}, 102: {7,8,9} } (etc...) 
} 

のように。私は上記の簡潔さを簡潔にしておきましたが、私は静的なデータ(顧客のID)を使って1回のAPIコールを開始し、次にそこからデータの「ツリー」を構築しようとしていることは明らかですAPI応答に含まれるものを使用して呼び出します。

私は約束、$ q.all、.thenなどについて知っていますが、私が試したことはすべて私が周りを円で回るようにします。素敵なコンパクトな関数を作り、各ビットを扱うことを忘れてしまいます。私は基本を理解していますが、複雑なものを組み立てる実際の現実世界の例は見たことがありません。

複数の非同期アクションを処理する方法を理解する助けになる人がいますか?特に、複数の非同期アクションをさまざまなループで呼び出す必要があり、移動する前に完了する必要がある場所はありますか?

PHPのようなサーバーサイド言語でこれをやったことがありますが、現在のアクションが完了するまでコードが進まない場合は簡単です。

私が試したコードのいくつかは投稿したいが、それはトータルジョークだ。

ありがとうございます。私はあなたが角度のコードを持っていると仮定しています:

+0

「約束」を使用します。あなたはこれをチェックすることができます:https://docs.angularjs.org/api/ng/service/$http もし安心すれば '$ resource'も使うことができます。 – batmaniac7

+0

あなたが言ったように、あなたのコードを投稿してください。多分助けてください。 – developer033

答えて

0

あなたはpromises を使用することができますがP.S

someService.getCustomer().then(response => { 
    // call next api 
    someService.getOrders().then(resp =>{ 
       // call next api and so on 
    }); 
}); 

最初のAPIを呼び出すことを検討してください。

+0

私はそれをすべて見ました。これは、ループ内でAPIルックアップがあり、移動する前に各ループが終了するのを待たなければならない、このような複雑なものでは役に立ちません。 – user3565424

+0

あなたが探しているものが分かるまで待たなければなりません。どのようにあなたはそれをスキップすることができますか分からない。もしあなたが必要なすべてのデータを一度に持っていれば。 – batmaniac7

+0

また、そのようにすると(たとえそれが機能しても)大量の入れ子になってしまいます。それらのうち少なくとも4つは、大部分の中にループがあることを忘れないでください。私は反パターンとしての資格があると信じています。 私は各ステップがそれ自身の機能であるところでそれを行う方法を理解する必要があります。それぞれが順番に呼び出され、そのデータを返し、次の関数が呼び出されます。 – user3565424

0

私は非常に角度を経験していない、と私はいくつかのミスを犯したかもしれないが、これは私のプロジェクトだった場合、私は、以下の方法を試します:

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

あなたのモジュールを作成し、サービスを作成します。

:アグリゲータ

app.factory('aggregator', ['$q', function($q) { 
    var aggregator = {}; 

    // object properties and method here 

    return aggregator; 
]}; 

と呼ばれる次の操作を行うことができるはず

aggregator.getCustomer = function(customerID) { 
    // this is where you would implement calls to your api 
    // however, as api calls take long, it is a good place to use 
    // a promise because you can sort of synchronize asynchronous functions this way 
    // before returning the promise, you need to define what happens 
    // when you receive some response 
    // implementation further down the answer 
}; 

aggregator.getCustomerPreviousOrders = function(customerID) { 
    // implementation to follow 
}; 

aggregator.getOrderedProducts = function(orderIDsArray) { 
    // implementation to follow 
}; 

aggregator.getRelated = function(productID) { 
    // implementation to follow 
}; 

これらのメソッドのそれぞれは、約束を返す必要があり、あなたは呼び出しているAPIのどの部分に関係なく、ほぼ同じ方法で動作します。例えば

は、顧客は、このように行うことができるばかり:

aggregator.getCustomer = function(customerID) { 
    // make sure you have injected $q 

    // first you create an object that will be able to: 
    // 1. promise your customer data to another object 
    // 2. call api 
    // 3. if result returned from api call is positive, it passes the results to the object it made the promise to 
    // 4. if result is negative, it rejects the promise it made before, 
    // thus, still providing some answer 
    // With $q, you create this object by calling $q.defer() 
    var result = $q.defer(); 

    // Then you make your api call 
    $http({ 
       method: 'GET' 
       ,url: 'api/customer' 
       ,params: { id: customerID } 
     }).then(function callbackSuccess(response) { 

      result.resolve(response); // in success callback you resolve and include the response in promise resolution. When this happens, you will be able to proceed to the next api call 

     }, function callbackError(error) { 

      result.reject(error) // in error callback you reject and include the error in promise rejection. When this happens you will stop your chain of api calls and get an error which you can handle nicely 

     }); 



    // Then, as you will reach the end of this function before you receive api response, you must return a promise, so that the object that called this getCustomer function can hold on to something at least 
    return result.promise; 

} 

その後、同じ原理を使用して他のすべての機能を定義し、次に、あなたは、このように、あなたのコントローラでこれらのAPI呼び出しをチェーンすることができます:

app.controller('someController', ['$scope', 'aggregator', function($scope, aggregator) { 

    $scope.onCustomerSelected = function(id) { 
     $scope.customerID = id; 
    } 

    $scope.loadData = function() { 
     // in here you can chain your aggregator functions 
     aggregator.getCustomer($scope.customerID) // wherever your customerID comes from 
     .then(aggregator.getCustomerPreviousOrders(response)) 
     .then(aggregator.getOrderedProducts(response)) 
     .then(aggregator.getRelated(response)) 
     .then(function(response) { 
      // here you finally handle your response with all the collected data 
     }) 
     .catch(function(response) { 
      // here you handle any errors that come up in the chain of api calls 
      // whichever call ends up with an error will be handled by this handler and that is one elegant way to handle errors 
     }); 
    } 

    $scope.loadData(); 
}]); 

EDIT - 周りの閲覧は、私はより多くのオプションhereを見つけました。見て、私はそれが助けてくれることを願っています。

関連する問題