1

node.js では、array.forEach がブロックしていることを知っています。

配列をループして、次のような文字列を作成する必要があります。

var rarray = ['test', 'test2'];
var rstring = '';
  rarray.forEach(function(e, i){
  rstring = rstring + i + e;
});
return rstring;

非同期で行うにはどうすればよいですか?

4

4 に答える 4

1

私はあなたがやろうとしていることは実際にはと呼ばれていると付け加えるかもしれませんreduce。あなたはそれをこのように書くことができます(doc

var res = array.reduce(function(prev, current, index) {
  return prev + index + current ;
}, '');

非同期で行うことは、この方法で行うことができます

var array = ['one', 'two'];

function reduceAsync(collection, initial, process, callback) {
  var i = 0;
  var res = initial;
  function DO(err, result) {
    if(err) return callback(err);
    if(i > collection.length) return callback(null, res);
    var index = i++;
    var value = collection[index];
    process(res, value, index, collection, DO);
  }
  DO(null, res);
}

reduceAsync(array, '', function(previous, current, index, collection, callback) {
  setTimeout(function() {
    callback(null, previous + index + current);
  }, 10); // wait 10 ms 
}, function finalResult(err, result) {
  console.log(result);
})

または、あなたが知っている、あなたはasync.reduceを使うことができます

于 2013-03-01T10:23:45.693 に答える
1

このような場合、おそらくこのコードを非同期バージョンに変換する必要はありません。

仮説として、または非常に大きな配列の場合、コードを非同期のもの、または少なくともメイン イベント ループに定期的に戻るものに変換する方法があります。

var rarray = ['test', 'test2'];
var rstring = '';
var max = rarray.length;
var current = 0;

process.nextTick(function next() {
  rstring = rstring + rarray[current++];
  if (current >= max) {
    console.log("done", rstring);
  } else {
    process.nextTick(next);
  }
});

console.log実際には、これを関数でラップし、完了コールバックを呼び出して置き換えます。

于 2013-03-01T06:36:08.737 に答える
0

上記のコードで非同期モジュールを使用する場合でも、同期コードになります。非同期モジュールを使用すると、コールバックの地獄を回避し、コールバックを管理できます。同期非同期にはなりません。これを実現するには、Pascalの回答のようにprocess.nextTickを使用する必要があります。

配列内の各アイテムに対して追加の非同期処理を実行していて、順序を維持しながら各操作の結果を集約する場合は、次のようにasync.eachSeriesを使用できます。

var async = require('async');
var rarray = ['test', 'test2'];
var rstring = '', i = 0;

async.eachSeries(rarray, function(item, callback){
    rstring += (i++) + item;
    callback();
  }, function(err){
    console.log(rstring);
  }
);

順序に煩わされていない場合は、async.eachを使用すると、非同期処理関数が並行して実行されます。

于 2013-03-01T10:23:16.117 に答える
0

Pascal の答えは、基本的に協調マルチスレッドの形式です ( Wikipedia: Threadを参照)。

測定せずに言うのは難しいですが、コンパイラにはループの最適化を行う機会があるため (上記のコードで具体的に起こるかどうかはわかりません)、プリエンプティブ マルチスレッドはこの性質のものに対してスループットが向上すると思います。システムは、タスクを切り替える頻度を正確に決定するのに適している可能性があります。node.js でWeb Worker Threadsを実行できるようです。

誰もベンチマークを持っていますか?

于 2013-03-01T06:58:07.683 に答える