2016-08-07 17 views
1

現在、このコードは配列の最初の約束が直ちに解決されるため、ゼロを出力します。約束をどのように解決するのか?

const promises = []; 
 
const promiser = (number) => new Promise((resolve, reject) => window.setTimeout(() => resolve(number), number * 100)); 
 
for (let index = 0; index < 10; index++) { 
 
    const promise = promiser(index); 
 
    promises.push(promise); 
 
} 
 

 
Promise.race(promises).then(r => console.debug(r));

私は最速の約束が解決したら、それはpromises配列から削除され、新しいPromise.raceコールが無になるまで繰り返し、残りの約束で作られるようにそれを作るために探しています約束が残っている。

Promise.raceは、約束の結果ではなく約束の結果を返すので、私はその約束を特定することができず、解決されたものはどれか分かりません。これを知る方法はありますか?私は、ある種の相関キーとその結果を持つ複雑なオブジェクトを返すことができると思いますが、それは変です。 Promise.raceコールバックの2番目のパラメータが約束のインデックスになることを期待していましたが、それは当てはまりません。thenはもう1つの約束のthenなので意味がありません。とにかくインデックス。あなたはより良い方法を考えることができますか?

また、私はすべての約束事を最初のraceで実行しますが、その後のracesの問題ではないでしょうか?その間に別の約束が解決された場合は、それ以降のraceコールが行われる前に、それを返すだけで問題はありません。その間に複数の約束が解決された場合は、最初の配列を配列順または解決順序で返し、次にraceは2番目を返します。

私は配列を歩いてisResolvedの約束を取り除くこともできましたが、それは本当のことではありません。しかし、たとえそれがあったとしても、raceへの呼び出しの間に複数の約束が解決された場合、これは完全に中断されます。

+1

プロミスは、将来の価値だけでなく、約束を識別する値に解決することができますか?例の場合は、あなたの価値はインデックスなので、あなたが望むことをするのは簡単ですコード –

+0

プロミス。race()は、あなたが決議のうちの1つだけを気にするときに使用されます。 - 逐次実行の場合は、単一の約束に.then()節を追加するだけで、約束を返すこともできます。 - パラレル実行の場合、Promise.allをMattias Buelensの回答 –

答えて

1

あなたがそのようなあなたが(Promise.reduceまたはPromise.anyのような)もっと自分のコードを構造化することができますいくつかの有用性を見出すことができbluebirdとして有望ライブラリで作業している場合は、とにかく約束

const promises = []; 
const promiser = (number, id) => new Promise((resolve, reject) => window.setTimeout(() => resolve({ number, id }), number * 100)); 
for (let index = 0; index < 10; index++) { 
    const promise = promiser(index, "id_" + index); 
    promises.push(promise); 
} 

Promise.race(promises).then(r => console.debug(r.id)); 

に識別子を返すことができます私は最速の約束が解決したら、それはpromises配列から削除され、新しいPromise.raceコールが無になるまで繰り返し、残りの約束で作られるようにそれを作るために探してい

+0

としてください。中間の段落で。これは私が作っていない約束でこれを使うことができないので駄目です。私はBluebirdを見て、それが自分のニーズに合っているかどうかを見ていきます。 –

+2

'.then(r =>({result:r、id:someIdentifier}))))') ''の行に沿って何かを使って、あなたが作成していない約束と共に使うことができます。配列 –

+1

良い点! BTW @drinchev Bluebirdは、私が「約束」がどのような順序で解決するかは関係ありませんので、私はすぐにそれぞれを処理する必要があるので、「それぞれ」と「減らす」の両方を順番に実行しているようです。しかしIDとあなたと@ジャロマンダXが提案したトリックは、私のために働くだろう、再びありがとう。 –

4

約束が残っている。

は、なぜあなたは、あなたが最終的にすべて約束を処理したい場合はPromise.raceを使用するようにしたいですか?解決するとすぐにすべての約束を処理し、すべての約束事が処理されるまで待つことはできませんか?

const promises = []; 
const promiser = (number) => new Promise((resolve, reject) => window.setTimeout(() => resolve(number), number * 100)); 

for (let index = 0; index < 10; index++) { 
    const promise = promiser(index) 
     .then(r => process(r)); // process every promise individually 
    promises.push(promise); 
} 

Promise.all(promises) // wait for all promises to be processed 
     .then(r => console.debug('all done!')); 

それともprocess非同期であり、そしてあなたが唯一の約束は一度に処理取得されていることを確認する必要がありますか?

+0

最初は、 'process'も非同期にしたいと思っていましたが、私の問題をさらに調べているうちに、私はそれがなくてもできるようになりました。彼らが私の質問に答えたとき、@ drinchevの答えはマークされたままにしておきますが、あなたが間違った質問をしているのを助けてくれました。ありがとうございました。 –

+0

これは正しい答えです。 - forループの3行は単一のプッシュ式でなければなりません - 最初の拒否または例外を取得するPromise.all()。then()の最後に.catchを追加する必要があります。 –

関連する問題