n個の非同期関数をまとめて処理したい状況で、Promise.all()を使うことでうまく切り抜けられたのでそのメモ。
参考
今回出くわした状況
ソース
class hoge { name = null; constructor(name) { this.name = name; } // resolveを返す非同期関数 hidouki() { return new Promise(resolve => { setTimeout(() => { resolve(this.name); }, 1000); }); } }
class fuga { hoges = []; startHoge(name) { this.hoges.push(new hoge(name)); } }
hogeクラスは時間がかかる非同期関数hidouki()
を持つ。fugaクラスの startHoge()
が 呼ばれるたびにhoges[]
フィールドにhogeインスタンスが格納される。何度呼ばれるかはわからない。この各hogeインスタンスのhidouki()
をまとめて並列処理したい。
解決方法
fugaクラスにまとめて非同期処理を行うメソッドmatometeHidouki()
を実装。
class fuga { hoges = []; startHoge(name) { this.hoges.push(new hoge(name)); } matometeHidouki() { return new Promise(resolve => { // Promise.all()の引数に渡すiterableオブジェクト let hidoukis = []; // 各インスタンスのhidouki()をhidoukis[]にpushしていく for (const i in this.hoges) { hidoukis.push( new Promise(resolve => { this.hoges[i].hidouki().then(name => { return resolve(name); }); }) ); } Promise.all(hidoukis).then(data => { resolve(data); }); }); } }
呼び出し側
const fuga = new fuga(); fuga.startHoge('tarou'); fuga.startHoge('jirou'); fuga.startHoge('saburou'); fuga.matometeHidouki().then(data => { console.log(data); // expected output: Array ['tarou', 'jirou', 'saburou'] });
これで、n個の非同期関数をまとめて並列処理することができる。各resolve()の値が配列になって返ってくるので、あとは煮るなり焼くなり。。。
以上。