2016-11-23 4 views
0

私はjavascriptの約束AとCがあります。ここでBは約束を返す関数です。並行してチェーンされたjavascriptの約束

私の現在のコードは、おおよそように見えます

A--->B---> 
C--------> 
      D------> 

BはAからの出力を利用しており、DはBからの出力を利用し、C:これは私が流れるようにしてみたい方法です

var runPromises = []; 
runPromises.push(A.then(B)); 
runPromises.push(C); 

Promise.all(runPromises).then(values => console.log(values)); 

AとCが実行されているのが見えますが、AとCがログアウトするまでBは実行されません。実行のための正しいパターンは何ですか? AとBは包括的な約束に入れる必要がありますか?

はJaromandaの正しい答えを説明するために、私の元の質問へ追加するには:私のB機能は、おおよそように定義されました:http.getが戻って豊かにできる前

var B = function(inputA){ 
    return new Promise(function(resolve, reject){ 
     http.get(site, function(done){ 
      inputA['site'] = done; 
     } 
    resolve(inputA); 

これはinputAを解決しました。 inputA。チェーンの約束に

+0

あなたのコードが正しい - 約束のAとC、および関数Bのおそらく最も重要な定義に関するより多くの情報を提供してください - 関数Bが約束を返さないと思っている –

答えて

1

、次いでA.then(B)が結果として返されます。 .thenへの引数は、FUNCTION、ない約束

Bは、(下記のコメントによる)FUNCTIONではなく、PROMISE(ようであれば何がやりたいことは

Promise.all([A.then(result=>B), C]).then(values => console.log(values)); 

のようなものでなければなりません

Promise.all([A.then(result=>B()), C]).then(values => console.log(values)); 
//---------------------------^^ 

以上単に

:質問)ごとに、それは簡単な変更です
Promise.all([A.then(B), C]).then(values => console.log(values)); 

これは基本的にあなたが質問で持っていたものなので、問題の内容は今混乱していますか?それはconsole.logに表示される値ですか?

var delay = (timeout, value) => new Promise(resolve => { 
 
    setTimeout(() => {resolve(value); console.log('done', value);}, timeout); 
 
    console.log('begin', value) 
 
}); 
 

 

 
var A = delay(3000, 'valueOfA'); // A is a Promise 
 
var C = delay(2000, 'valueOfC'); // C is a Promise 
 
var B = valA => { 
 
    console.log('B called with', valA); 
 
    return delay(1000, valA + ':valueOfB'); // include valA to show that the resolved value of B depends on the resolved value of A 
 
} // B is a function that returns a Promise and uses the resolved value of A as input 
 
Promise.all([A.then(B),C]).then(values => console.log(values));

+0

Jaromanda、私はBが約束を返す関数であるべきだと謝った。つまり、あなたが提案した解決策は私にとってはうまくいかないようです。 AとCの結果を返す代わりに、B関数とCの結果を返します。 – scott

+0

もちろん結果はBとCですが、それらはあなたが** Dを続ける前に待つべき2つの約束です.BはAが完了するまで実行されません。これはあなたの質問の100%の図と一致します。あなたの元の質問の唯一の欠点は、あなたが '.then'を間違って使っていたことでした。 –

+0

しかし、console.logが実行されているときにはCは約束していますが、Bは関数を返すだけです。私はBをどのように実現する約束にするかを決定しようとしているので、console.logが実行される前に約束のBとCの結果を得ることができます。 – scott

1

、あなたは.then()を使用することができますが、パラメータは次の約束を返す機能する必要があります。正しいコードは次のようになり:A、B及びCが約束されている場合は

var runPromises = []; 
runPromises.push(A.then(() => B)); 
runPromises.push(C); 

Promise.all(runPromises).then(values => console.log(values)); 
+0

私がJaromandaに言及したように、4castleは、Bが約束を返す関数であると指定しておかなければならないことを謝ります。つまり、あなたが提案した解決策はJaromandaのものと同じ結果をもたらし、私のために働くようには見えません。 AとCの結果を返す代わりに、B関数自体とCの結果を返します。 – scott

1

他の回答で述べたように、我々は「B」は約束ではなく、約束自体を設定する関数であると仮定した場合、あなたは「B」は、実行すべきことを正しいです"C"に頼ることなく。あなたは小さなテストでこれを証明することができます。

let start = Date.now(); 
function debug(p) { 
    p.then((r) => { 
    let secs = ((Date.now() - start)/1000).toFixed(2) 
    console.log(secs + "s: " + r); 
    }); 
} 

let a = new Promise((r) => { 
    setTimeout(r, 0, "a done"); 
}); 
debug(a); 

let b = a.then((res) => { 
    return new Promise((r) => { 
    setTimeout(r, 0, res + ":b done"); 
    }); 
}); 
debug(b); 

let c = new Promise((r) => { 
    setTimeout(r, 1000, "c done"); 
}); 
debug(c); 

Promise.all([b, c]).then((res) => { 
    console.log("result: " + JSON.stringify(res)); 
}); 

結果で:

0.00s: a done 
0.01s: a done:b done 
1.00s: c done 
result: ["a done:b done","c done"] 
+0

Btw、 'setTimeout'はコールバック関数のパラメータを受け入れますので、' setTimeout(r、1000、 "c done"); ' – zerkms

+0

nice、@zerkmsへの呼び出しを単純化することができます。更新された答え。 –

+0

David、レスポンスありがとう - 私はあなたのコードを完全に理解していますが、それはうまく機能しますが、なぜそれが私のものと違うのか理解できません。あなたがbを渡す代わりにa.then(b)を渡している場合(それはa.then(function_i've_defined_as_b)を実行しています)、違いは何ですか? – scott

関連する問題