2016-05-25 6 views
1

私は現在jquery.deferredパターンを使用して自分のウェブサイト用の簡単なライトボックスを構築していますが、その間に非同期操作のフラットチェーンを維持し、悪名高いネストされたコールバックピラミッドの運命。jquery - 遅延チェーンを介して変数を渡してネストを避ける

$('#gallery a').click(function() { 

    var id = $(this).attr('id'); // Id of the current selection 
    var current = 0;    // Array index of the current item 

    getTpl()      // Get and load lightbox template 
     .then(getData)    // Get JSON data of the selected item 
     .then(getItem)    // Pass JSON data and get the item 
     .then(loadItem)    // Use JSON data to create the HTML output 
     .done(function() { 
      // Wrap everything up, intialize the lightbox controls 
      // (requires the JSON data) and load the lightbox 
     }); 
}); 

最初の2つのステップ(getTpl、のgetData)は、単純なAJAXの約束や仕事の罰金です:ここでは私がこれまで持っているものです。さらにJSONデータをチェーンの3番目のステップ(getItem)に渡すこともできます。

  1. 私はチェーン(のgetItemとloadItem URLを構築するためにこれらの変数を使用して作成時に呼び出される関数への高い範囲から変数「ID」と「現在」を渡すことがあります。それは問題が起動ところですHTML出力)。非同期チェーンを壊すことなく、どうすればいいですか?
  2. JSONデータ(およびその他の変数)は、実際にチェーンを使用する方法に沿ってすべての関数から返さなければなりませんか?データと必要な変数をチェーン全体で利用できるようにする簡単な方法はありませんか?
  3. ランダムな操作をチェーンにスローすることはできますか?シンプルなjqueryフェードイン?それは、 '.done'が新しい約束を期待しているからです。

ありがとうございます!あなたはこのようにそれを行う場合

答えて

1

:次に

var id = $(this).attr('id'); // Id of the current selection 
var current = 0;    // Array index of the current item 

getTpl()      // Get and load lightbox template 
    .then(getData)    // Get JSON data of the selected item 
    .then(getItem)    // Pass JSON data and get the item 
    .then(loadItem) 

、あなたはチェーンであなたの次の関数の引数を設定するために約束システムにそれを残しています。 promiseシステムはチェーン内の前の操作からの戻り値を使用するため、これらのすべてに引数を渡したい場合は、すべての関数を渡す必要があります。この正確な構造では、その周りに道はありません。

チェーンとのデータ共有のためのより一般的なアプローチについては、以下を参照してください

How to chain and share prior results with Promises

次のように変数の任意の数を通過するための一般的なスキームは、オブジェクトに入れることですし、ちょうどそれぞれを持っています関数はacceptとobjectを返し、そのオブジェクトを返します。

var options = { 
    id: $(this).attr('id'),  // Id of the current selection 
    current: 0     // Array index of the current item 
}; 

getTpl(options)     // Get and load lightbox template 
    .then(getData)    // Get JSON data of the selected item 
    .then(getItem)    // Pass JSON data and get the item 
    .then(loadItem) 

その後、各機能getTpl()getData()getItem()loadItem()は、彼らの最初の引数は、このオプションのオブジェクトであることを期待することができ、それらはすべてのオプションがオブジェクトことで解決する必要があります。彼らは、鎖を介して渡されるオブジェクトに新しいプロパティを自由に追加することができます。


他の構造化オプションがあります。

var id = $(this).attr('id'); // Id of the current selection 
var current = 0;    // Array index of the current item 

getTpl()      // Get and load lightbox template 
    .then(function() { 
     // code here can directly access current and id variables 
    }).then(...) 

それとも、あなたが直接あなたの関数を呼び出すと、彼らが必要とするものは何でも変数にそれらを渡すことができます:

var id = $(this).attr('id'); // Id of the current selection 
var current = 0;    // Array index of the current item 

getTpl()      // Get and load lightbox template 
    .then(function() { 
     return getData(id, current); 
    }).then(function(data) { 
     return getItem(data, id); 
    }).then(function(item) { 
     return loadItem(item, current); 
    }); 
+0

私はすでに覚えて/考え出しあなたの関数がインラインである場合、それらは直接範囲内で一部の変数にアクセスすることができます変数を保持しているオブジェクトを宣言するだけで、チェーンを介して変数を追加することができます。愚かな私! 操作を別々の関数に分割する理由は、これらの操作を別の場所から呼び出すことができ、コンテキストに応じてチェーンが変更される可能性がある(チェーンにランダムメソッドを投げた場合)。別々の機能を持ち、状況に応じて必要に応じてそれらを連鎖させるのがよい方法だと思った。これを処理するスマートな方法があれば、教えてください。 – sverebom

+0

@ user3330116 - 私はあなたにすでに3つの別々のアプローチを提案しました。私は個人的には、最も柔軟性の高いオプションオブジェクトを選択するでしょう。各関数は、この環境で使用できる、または別々に呼び出されたときに、そのオブジェクトに対して必要な/期待されるプロパティを持ちます。しかし、チェーン化するときに他のプロパティを渡す柔軟性が得られます。 – jfriend00

+0

これは私が今やったことですが、それは魅力のように機能します。 「チェーンを通してオブジェクトを渡す」というアプローチが鍵でした。清潔でシンプル。 JSでのオブジェクトの一般的な使用とPromisesのワークフローに関する追加情報を思い出してくれてありがとう。 – sverebom

関連する問題