

node.js上で動かすJavaScriptのコードでオブジェクトの配列があったとして、forEachでまわすときに、それを並列で動かすことは可能でしょうか？(可能であればPromiseで)

[code]

    var obj = [{a:"abc",b:123,c:true},{a:"efg",b:456,c:true},{a:"hij",b:789,c:false}];
    obj.forEach(function(data){
        //ここに処理
    });
    
[/code]

このdataを並列で処理する場合はどのように書けばよいのでしょうか？


CC BY-SA 3.0
2015-05-19T08:47:00.970
10363
2016-02-26T11:53:16.443
2015-05-19T08:47:46.633
440
9793
question
node.js
node.jsのforEachを並列に行う方法は存在しますか？


ただ遅延させて他の処理を優先させたいということならば、  
setTimeout等を使えばいいと思います。  
例のようなものではどうやってもオーバーヘッドの方が高くつきそうですが。

または本当にパラレルで処理したいということであれば、  
Mozillaが取り組んでいたParallelArrayのようなものもあります。  
それをChildProcessとPromiseなんかを使って再現してもいいですが、  
よっぽどdataに対して重い処理を行わない限りやはりオーバーヘッドの方が高く付くでしょう。


CC BY-SA 3.0
2015-05-20T04:27:43.210
10405
2015-05-20T04:27:43.210
5721
10363
answer


追記2016/02/26：「並列処理」と「非同期処理」を混同して回答していました。下記回答は、`obj`の各要素を受け取った非同期的な処理に対して、「全ての処理完了を待つ」ものと「最初に完了した処理を待つ」例として残しておきます。

* * *

`Promise.all`（ ~~並列~~ 各処理を実行して全ての処理完了を待つ）または`Promise.race`（ ~~並列~~
各処理を実行して最初に終わった処理だけ待つ）を使います。

index.js

[code]

    var obj = [
      {a:"abc",b:123,c:true},
      {a:"efg",b:456,c:true},
      {a:"hij",b:789,c:false}
    ];
    
    var promises = obj.map(function(data) {
      return new Promise(function(resolve, reject) {
        // ここに処理
        var delay = Math.floor(Math.random() * 5000); /* ランダムに0〜5秒 */
        setTimeout(function() {
          console.log('processing:', delay + '[msec]', data);
          // 完了（成功）時には resolve() を、失敗時には reject() を呼ぶ
          resolve(data);
        }, delay);
      });
    });
    
    Promise.all(promises).then(function(results) {
      console.log('results:', results);
    });
    
[/code]

実行結果の一例は以下のようになります。ランダムで待ち時間を設定しているので実行のたびに結果が変わります。

[code]

    % node -v
    v5.5.0
    % time node index.js
    processing: 1099[msec] { a: 'efg', b: 456, c: true }
    processing: 1975[msec] { a: 'abc', b: 123, c: true }
    processing: 2648[msec] { a: 'hij', b: 789, c: false }
    results: [ { a: 'abc', b: 123, c: true },
      { a: 'efg', b: 456, c: true },
      { a: 'hij', b: 789, c: false } ]
    node index.js  0.10s user 0.02s system 4% cpu 2.735 total
    
[/code]

`time`は最終行のように実行時間を出力するコマンドで、`node
index.js`の実行時間(total)が最も時間がかかった処理と同程度になっていることから並列処理されていることが分かると思います。

`Promise.race`を使うと以下のように、最初に完了した時点で後続の処理(`then`以下)が実行されます。

[code]

    % node -v
    v5.5.0
    % time node index.js
    processing: 663[msec] { a: 'hij', b: 789, c: false }
    results: { a: 'hij', b: 789, c: false }
    processing: 727[msec] { a: 'abc', b: 123, c: true }
    processing: 2264[msec] { a: 'efg', b: 456, c: true }
    node index.js  0.08s user 0.02s system 4% cpu 2.333 total
    
[/code]

この場合の`index.js`は、最後の部分を以下のようにしています。

[code]

    Promise.race(promises).then(function(results) {
      console.log('results:', results);
    });
    
[/code]

参考：[Promise - JavaScript |
MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)


CC BY-SA 3.0
2016-02-24T07:57:05.717
22478
2016-02-26T11:53:16.443
2016-02-26T11:53:16.443
14466
14466
10363
answer