2017-01-16 3 views
6

異種の約束の集合の特定のケースにおいて、約束チェーンを平坦化するのに役立つQ.reduceおよびQ.allなどのメソッドがあります。しかし、一般的なケース:"インデントピラミッド"を使わないで任意のプロミスチェーンを正しく表現するには?

const F = (x) => x; 
const a = F(1); 
const b = F(2); 
const c = F(a + b); 
const d = F(a + c); 
const e = F(b + c); 
console.log(e); 

つまり、各用語が事前に定義された任意の用語に依存する一連の割り当てです。

const F = (x) => Q.delay(1000).return(x); 

私はインデントピラミッドを発生させることなく、そのパターンを表現する方法はありませんで考えることができます:返された値を使用して動作しないだろうと

F(100).then(a => 
    F(200).then(b => 
    F(a+b).then(c => 
     F(a+c).then(d => 
     F(b+c).then(e => 
      F(d+e).then(f => 
      console.log(f) 
     ) 
     ) 
    ) 
    ) 
) 
); 

注:

Fが非同期呼び出しであると仮定
F(100).then(a => F(200)) 
    .then(b => F(a+b)) 
    .then(c => F(a+c)) 
    .then(d => F(b+c)) 
    .then(e => F(d+e)) 
    .then(f => console.log(f)); 

たとえば、aは2行目には含まれないため、この状況に対処する適切な方法は何ですか?その後の操作は、以前の操作の複数のビットに依存している方法のための

+2

ここにはさまざまな方法があります:[前回の結果を約束して連鎖する方法](http://stackoverflow.com/questions/28714298/how-to-chain-and-shrop-prior-results-with-promises/28714863 #28714863)。実際には、この質問はその質問のダップかもしれません。 – jfriend00

+0

@ jfriend00:それは間違いなく、同じものを複製したものです。 –

+0

間違いなく重複しています。私は、このスレッドは全体的にもっと有益なものになっていると思います。 – MaiaVictor

答えて

3

、あなたの選択肢は次のとおりです。

  1. はあなたが

  2. は、チェーンの外の変数を入れて、それらを割り当てる何をやったかですかあなたが行くよう

  3. abでオブジェクトの周り渡す全体のものを持って、そしてその上に、このような特性として

#1は私が固執するものです.は本当にのいずれかを実行するのに適しています。幸いにも、そのような蓄積はあなたの質問に示されるように深刻なことはめったにありません。


あなたは、彼らはそれを簡略化することができる方法についてSterling's answerを参照して、その後、(the proposalが終了し、彼らはES2017になるだろう、とあなたはtranspilerで今それらを使用することができます)早期async/awaitを採用したい場合。ここに実例(live on Babel's REPL)があります。

+0

async/awaitはスコープに役立ちます。また、Promise.all()iircを使用すると、連鎖パラメーターを簡単にすることができます。 (私はノードのための非同期ライブラリを使用しており、パラメータを簡単に渡します) –

+0

@ asterling/'await'は**非常に良い点です今)。 –

+0

投稿者はもっと良い答えを笑、我々はそのアイデアのためのJSのチャットで荷物に感謝できる –

3

2回目の試行です。 JSチャットの@荷物は、Async/Awaitを使用してあなたのパラメータの範囲を維持することを提案しました。

let a = await F(200); 
let b = await F(a + 100); 
let c = await F(a + b); 
//... etc, all inside an async function 

また、私は、これらの問題を滝を助けるためにasyncのlibを使用しました(これは私の経験です)Promise.allを使用するか、または可能性があります。それはES2017サポート/ transpilingが必要になりますけれども

async.waterfall([ 
    (callback) => { 
     let a = F(200); 
     callback(null, a) 
    }, (a, callback) => { 
     let b = F(a+b); 
     callback(null, b); 
    }, //etc down the chain 
]); 

私はPromise.allは、非同期のlibよりも良い、それを管理するだろうと思うが、非同期は/待つが、ここではきれいな方法です。

2

Async/awaitはこの問題を非常にうまく解決します。

async function runAsync(){ 
    const F = async (x) => x; 
    const a = await F(1); 
    const b = await F(2); 
    const c = await F(a + b); 
    const d = await F(a + c); 
    const e = await F(b + c); 
    console.log(e); 
} 

function runSync(){ 
    const F = (x) => x; 
    const a = F(1); 
    const b = F(2); 
    const c = F(a + b); 
    const d = F(a + c); 
    const e = F(b + c); 
    console.log(e); 
} 

runSync(); //5 
runAsync(); //5 

これは残念ながらnode --harmony-async-await example

を使用してノード7でネイティブに実行されます、あなたはおそらく一般的な使用のためにダウンtranspileする必要がありますし、出力は非常に大きくなる可能性があります。

+0

非常に良いnodejs非同期/待機モジュールがあります –

関連する問題