2

「非同期関数でforループを使用しないでください!」と叫び始める前に。コールバック内から次の反復を呼び出す非同期関数を使用してループをプログラムする方法を知っていることを述べさせてください。

しかし、コールバックに関心がない場合、または前のバージョンが終了した場合にのみ1回の反復を処理することに関心がない場合は、どうでしょうか。私の場合、xmlファイルから多数のレコードをインポートしてmongoDBに書き込んでいます。私の「書き込み」関数の通常の呼び出しは次のようになります。

asyncWrite( record, function(err, result) {
    ...
});

今私が言ったように、私はコールバック(エラーは発生しません!)にもシリアルプロセスにも興味がありません。そこで、forループを使用して、コールバックを省略しました。

for( i=0; i<max; i+=1) {
    asyncWrite( record_arr[i] );
}

小さい場合max、これは完全に機能します。しかし、max大きくなると(> 100.000)、「メモリ不足」エラーが発生します。これを防ぐ唯一の方法は、「通常の」非同期ループ(コールバック内からの再帰関数呼び出し)に戻すことでした。

他のアイデアはありますか?

4

1 に答える 1

6

非同期関数は、forループが機能するまで実行されません。頼りすぎるキューを集めたところです。大きなmax場合はout of memory、キューがいっぱいであるためエラーが発生します。console.log(process.memoryUsage());ループ内に挿入すると、メモリリークがどのように発生するかを確認できます。このタスクを処理するには、チャンクを操作する必要があります。

于 2013-02-03T10:07:38.257 に答える