2

私は小さなnodejsプログラムに取り組んでおり、プログラムのすべての非同期操作がいつ完了するかを知るのにいくつかの問題があります。

今のところ、プログラムは次の手順を実行します。

1/ いくつかのパラメーターを使用してプロセスを生成します。このプロセスは、標準出力にデータを出力します。

2/ プロセス stdout の「データ」イベントをリッスンし、何かが出力されるたびに、プログラムはデータを使用して関数 (「プロセス」と呼びます) を呼び出します。

3/ このプロセス関数は、最終的にデータを mongo データベースに挿入し、amqp サーバーにメッセージを送信します。

3/ データがなくなると、amqp と mongo データベースへの接続がまだ有効であるため、プログラムはアイドル状態になります。接続を閉じるには、すべての作業がいつ完了したかを知る必要があります。

それで、約束を利用するためにwhen.jsを使用しようとしましたが、私が達成しようとしていることをうまく機能させることはできません。

「プロセス」関数が promise を返すようにしました。これは、mongodb の挿入と amqp メッセージの送信が完了すると解決されます。私のプログラムでは、いつすべてが解決されたかを知るために when.all() を呼び出すことができるというすべての約束を受け取る配列を作成しています。

しかし、生成されたプロセスが stdout ストリームにデータを出力しているときに約束を非同期に作成しているため、 when.all() の呼び出しは空の配列で行われ、すぐに解決されるようです。

これは、私が達成していることを示すコードサンプルです。

var when = require('when')
  , _    = require('lodash')
  , cp   = require('child_process');

var promises = [];

function process(data) {
    var deferred = when.defer();

    setTimeout(function () {
        deferred.resolve(true);
    }, 3000); // Let's say we need 3 seconds to process and save data

    return deferred.promise;
}

var ls = cp.spawn('ls', ['-la', '/usr/bin']);
ls.stdout.on('data', function (data) {
    console.log('Received data, creating a promise to notify when this data is processed.');
    promises.push(process(data));
});

when.all(promises).then(function (values) {
    console.log('All promises are now resolved', values);
});

ご想像のとおり、このプログラムの出力は次のようになります。

All promises are now resolved []
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.

このコード サンプルでコンソール メッセージを予想どおりの順序で出力する方法はありますか (最初の行が最後に出力されます)。

ありがとう。

4

1 に答える 1

2

すべての約束がなされた後にのみ呼び出す必要があります。あなたのコメントであなたが言及した:

いつすべてがこのように行われるかを知ることはできないと思います

これは正しくありません。イベントを使用して、いつすべてが完了したかを知ることができます。close

ls.on('close',function(){
    when.all(promises).then(function (values) {
        console.log('All promises are now resolved', values);
    });
});
于 2013-12-11T19:29:46.937 に答える