web-dev-qa-db-ja.com

Promise.all()。then()解決しますか?

ノード4.xを使用するPromise.all(promises).then()がある場合、データを解決して次の.then()に渡すための適切な方法は何ですか?

私はこのようなことをしたいです。

Promise.all(promises).then(function(data){
  // Do something with the data here
}).then(function(data){
  // Do more stuff here
});

しかし、2番目の.then()にデータを取得する方法がわかりません。最初のresolve(...).then()を使うことはできません。私はこれができると思いました:

return Promise.all(promises).then(function(data){
  // Do something with the data here
  return data;
}).then(function(data){
  // Do more stuff here
});

しかし、それは正しいやり方のようには思えません...これに対する正しいアプローチは何ですか?

70
Jake Wilson

しかし、それは正しいやり方のようには思えません。

それは確かにそれを行うための適切な方法です(または少なくともa適切な方法でそれを行う)。これはpromiseの重要な側面です。それらはパイプラインであり、データはパイプライン内のさまざまなハンドラーによってマッサージすることができます。

例:

const promises = [
  new Promise(resolve => setTimeout(resolve, 0, 1)),
  new Promise(resolve => setTimeout(resolve, 0, 2))
];
Promise.all(promises)
  .then(data => {
    console.log("First handler", data);
    return data.map(entry => entry * 10);
  })
  .then(data => {
    console.log("Second handler", data);
  });

catchハンドラーは簡潔にするために省略されています。プロダクションコードでは、常には約束を伝播するか、拒否を処理します。)

私たちがそれから見る出力は次のとおりです。

第一ハンドラ[1,2] 
第二ハンドラ[10,20] 

これは、最初のハンドラーが2つの約束(12)の解決を配列として取得し、それぞれに10を掛けて新しい配列を作成して返すためです。 2番目のハンドラは、最初のハンドラが返したものを取得します。

追加の作業が同期的なものである場合は、最初のハンドラーにに入れることもできます。

例:

const promises = [
  new Promise(resolve => setTimeout(resolve, 0, 1)),
  new Promise(resolve => setTimeout(resolve, 0, 2))
];
Promise.all(promises)
  .then(data => {
    console.log("Initial data", data);
    data = data.map(entry => entry * 10);
    console.log("Updated data", data);
    return data;
  });

...しかし非同期の場合は、入れ子になってしまうのでそれをしたくないでしょうし、入れ子はすぐに手に負えないものになる可能性があります。

121
T.J. Crowder