0

誰かが私に次の行動の理由を説明してもらえますか?

nodejs / express Webサーバーがあり、次のコードを含む投稿ルートの1つがあるとします。

req.on('data', function() { console.log('data arrived'); })

このコードは期待どおりに機能し、呼び出されたときに「データが到着しました」というメッセージをコンソールに書き込みます。ただし、次のコードは次のとおりです。

setTimeout(function() { req.on('data', function() { console.log('data arrived'); }) }, 1000);

同じ状況にもかかわらず、何も印刷されません。短時間後にイベントをサブスクライブすると、リクエストオブジェクトストリームはどうなりますか?

これが必要な理由は、サーバーに大きなファイルをアップロードしたいからです。POSTリクエストが届いたら、データベースエントリを作成し、それにデータをパイプする必要があります。潜在的なサイズのためにデータチャンクをメモリに保存できませんが、データベースコールバックまたはコールバックからのリクエストオブジェクトのデータを取得できません。

この問題を解決する方法を知っていますか?前もって感謝します!

アップデート

次のコードはまだ機能しません。

req.pause();
setTimeout(function() {
    req.on('data', function(data) { console.log('data arrived'); })
    req.resume();
}, 1000);

UPDATE2

最終的な目標は、次のようなsgを実行することです。

req.pause();
doSometingAsync(function(result) {
    req.on('data', function(data) { doSomethingWithData(data, result) });
    req.resume();
});

、しかしこれはうまくいかないようです...

更新3

これにより、他に何もなしで単一の「経過」が発生します。

req.pause()
setTimeout () ->
    console.log 'elapsed'
    req.on 'error', (error) -> console.log error
    req.on 'data', (data) -> console.log 'in data'
    req.on 'end', () -> console.log 'end'
    req.resume()
, 2000
4

1 に答える 1

1

答え:

データが到着したときに起動req.pause();し、ファイルに書き込むようにデータを処理し、ファイル書き込みコールバックが起動したときにreq.resume();、次のパッケージを受信するために実行できます。

req.once代わりに使用しない限り、「データ」イベントを再定義するべきではありません。req.on

これにより、帯域幅が物理ハードドライブの速度に制限され、アプリが非同期に保たれ、RAMの使用量が減少します。

更新1回答:

これはいくつかの擬似コードです:

req.on("data", function (data) {
    req.pause();
    /* do something with data like the following: */
    some_method(some_value, data, function (success) {
        if (success) {
            req.resume();
        }
    });
});

またはこのようなもの:

req.on("data", function (data) {
    req.pause();
    console.log("data arrived");
    setTimeout(function(){req.resume();}, 1000);
});

UPDATE 2回答:コールバックを使用する必要があります

この場合、この関数が実行されるとすぐにdoSomethingWithData();起動するの3番目の引数。req.resume();

さらに、非同期を維持するには、次のようにコールバックを呼び出す必要があります。

var doSomethingAsync = function (data, result, cb) {
    /* do something with data and result */
    process.nextTick(function () {
        cb();
    });
};

req.pause();
doSomethingAsync(function (result) {
    req.on('data', function (data) {
        req.pause();
        doSomethingWithData(data, result, function () {
            req.resume();
        });
    });
    req.resume();
});

またはあなたはこれを行います:

var doSomethingAsync = function (data, result, req) {
    /* do something with data and result */
    process.nextTick(function () {
        req.resume();
    });
};

req.pause();
doSomethingAsync(function (result) {
    req.on('data', function (data) {
        req.pause();
        doSomethingWithData(data, result, req);
    });
    req.resume();
});
于 2012-10-15T15:40:56.990 に答える