2012-08-02 4 views
6

典型的なREST標準に従って、リソースを分けて別々のエンドポイントとコールに分割しました。ここで問題となる主な2つのオブジェクトは、ListItemです(もちろん、リストにはアイテムのリストとそれに関連する他のデータもあります)。クリーンな非同期ループを作成するには?

ユーザーが自分のリストを取得したいのであれば、彼はその後、ユーザはこれらのリストのいずれかでアイテムを取得したいと4が見つかったapi/ListItems/4に取得するかもしれないapi/Lists

にGET要求を行う可能性があります以前の呼び出しで取得されたList.listIdから属性が$.ajaxの場合、コールバックメソッドをポイントできるので、これら2つのイベントを合理化できます。

しかし、私がのすべての要素を取得したい場合、物事は非常に乱雑になります。問題のリスト。例えば、私はmakeGetRequestというライブラリ関数を持っていて、このコードをきれいにするためにエンドポイントとコールバック関数をとっているとしましょう。単純にこの3つの要素素朴な方法の結果を取得:

var success1 = function(elements){ 
    var success2 = function(elements){ 
     makeGetRequest("api/ListItems/3", finalSuccess); 
    } 
    makeGetRequest("api/ListItems/2", success2); 
} 
makeGetRequest("api/ListItems/1", success1); 

嫌!これは、私たちが手首を突き抜けてループを指し示しているプログラミング101のものです。しかし、どのように外部ストレージに頼ることなく、ループでこれを行うことができますか?

for(var i : values){ 
    makeGetRequest("api/ListItems/" + i, successFunction); 
} 

function successFunction(items){ 
    //I am called i-many times, each time only having ONE list's worth of items! 
} 

とにも保存して、私はすべてが終了し、そのデータを取得して、収集したすべてのデータを取得し、それを使って何かをするいくつかのマスタ機能を呼び出したとき知っておく必要があります。

これを処理する方法はありますか?これは前に何度も解決されている必要があります...

+0

JQuery $ .getと$ .each – mplungjan

+0

は、バックエンドですべてのものを取得するルートがない理由です。 'api/ListItems/all'またはそれに類するもの?任意の非同期ループの必要性を避けることができます。 – jackwanders

答えて

4

は、エンドポイント・パラメータのスタックを使用してみてください:

var params = []; 
var results []; 

params.push({endpoint: "api/ListItems/1"}); 
params.push({endpoint: "api/ListItems/2"}); 
params.push({endpoint: "api/ListItems/3"}); 
params.push({endpoint: "api/ListItems/4"}); 

次に、あなたがあなたの成功ハンドラで、それは再帰的にすることができます。

function getResources(endPoint) { 

    var options = {} // Ajax Options 
    options.success = function (data) { 
     if (params.length > 0) { 
      results.push({endpoint: endpoint, data: data}); 
      getResources(params.shift().endpoint); 
     } 
     else { 
      theMasterFunction(results) 
     } 
    } 

    $.get(endPoint, options) 
} 

そして、あなた次のような単一の呼び出しで開始できます。

getResources(params.shift().endpoint); 

E DIT:

自己が含まれているすべてのものを維持するために、グローバルなスコープの外には、関数を使用してコールバックを提供することができます使用で

function downloadResources(callback) { 

    var endpoints = []; 
    var results []; 

    endpoints.push({endpoint: "api/ListItems/1"}); 
    endpoints.push({endpoint: "api/ListItems/2"}); 
    endpoints.push({endpoint: "api/ListItems/3"}); 
    endpoints.push({endpoint: "api/ListItems/4"}); 

    function getResources(endPoint) { 
     var options = {} // Ajax Options 
     options.success = function (data) { 
      if (endpoints.length > 0) { 
       results.push({endpoint: endpoint, data: data}); 
       getResources(endpoints.shift().endpoint); 
      } 
      else { 
       callback(results) 
      } 
     } 
     $.get(endPoint, options) 
    } 

    getResources(endpoints.shift().endpoint); 

} 

を:

downloadResources(function(data) { 
    // Do stuff with your data set 
}); 
+0

反復が失敗すると、再帰に行きますか?非常にエレガントなソリューション!しかし、私はまだ 'params'と' results'を隠す場所を見つける必要があるので、呼び出しの間に範囲外にならないようにします。そこに何か提案はありますか?私は "グローバル変数"の不正行為を避けようとしています。 –

+0

@ngmiceli私は、エンドポイント配列を含むDownloadResources関数を提案します。この関数の引数としてcontinueコールバックを提供できます。詳細は私の編集を参照してください。 – dmck

2

dmckの答えは、おそらくあなたの最善の方法ですベット。しかし、もう1つのオプションは、バルクリストオプションを実行することで、apiはapi/ListItems /?id = 1 & id = 2 & id = 3のようなリクエストをサポートします。

あなたのパーソナルな美しさに合っていれば、api検索エンドポイントを行うこともできます。

+0

これは良い点であり、私が完全に見落とした非常に単純な解決策です。 @jackwandersのコメントにうまく行きます。私のAPIに大量のGETを処理し、すべてをまとめてクライアント側に戻す機能を与えます。これはまだRESTfulと考えられていますか? –

+0

GETプロトコルでデータを取得している場合は、URLがどれほどかわいくても、RESTfulです。そのエンドポイントがどのように機能すべきかについていくつかの疑問があります。これを「リスト」と呼びます。ここでは、より適切な名前がバルクリストまたは検索になります。 – Jordan

関連する問題