パイプの完了を処理するコールバック


196

次のnode.jsコードを使用して、URLからドキュメントをダウンロードし、ディスクに保存しています。ドキュメントがダウンロードされたときに通知を受けたい。パイプを使用したコールバックを見たことがありません。または、ダウンロードの完了時にキャプチャできる「終了」イベントはありますか?

request(some_url_doc).pipe(fs.createWriteStream('xyz.doc'));

回答:


302

ストリームはEventEmittersなので、特定のイベントを聞くことができます。あなたが言ったようにfinish、リクエストのためのイベントがあります(以前はend)。

 var stream = request(...).pipe(...);
 stream.on('finish', function () { ... });

利用可能なイベントの詳細については、ストリームのドキュメントページを確認してください。


12
var r = request(...).on("end",function(){/* CALLBACK */}).pipe(...);
— Denys Vitali

6
私にとっては、「終了」ではなく「閉じる」というイベントが機能するr.on('close'), function () {...})
— ジャドソン

9
「終了」イベントは「終了」パイプイベントになりました:nodejs.org/api/stream.html#stream_event_finish
— Pier-Luc Gendreau

13
「終了」イベントはまだ存在し、読み取り可能なストリームで使用されます。書き込み可能なストリームは「終了」を使用します。これは、Transformストリームが両方の組み合わせであり、イベントを区別する必要があるためです。
— noderman 2016年

16
このスレッドは、ノードストリームの操作方法の良い要約です。
— 爆撃機2017

43

ベースのnodejsドキュメント、http: //nodejs.org/api/stream.html#stream_event_finish 、それはwritableStreamのfinishイベントを処理する必要があります。

var writable = getWriteable();
var readable = getReadable();
readable.pipe(writable);
writable.on('finish', function(){ ... });

受け入れられた回答はノードv0.12.7では機能しませんが、ソリューションは機能します。
— Luca Steeb、2015

9

Webからhttp(s)経由でファイルシステムにコンテンツをパイプするためのコードスニペット。@starbeamrainbowlabsが気づいたように、イベントfinishはうまくいきます

var tmpFile = "/tmp/somefilename.doc";

var ws = fs.createWriteStream(tmpFile);
ws.on('finish', function() {
  // pipe done here, do something with file
});

var client = url.slice(0, 5) === 'https' ? https : http;
client.get(url, function(response) {
  return response.pipe(ws);
});

オンの「終了」は私には機能し、「終了」は機能しません。ありがとうございました!
— shaosh 2015

1
ある特定のケースでは、予想されるすべてのバイトが到着する前に終了が発生しているようです
— Michael

4

私はこのコンテキストに関する私の問題の少し異なる解決策を見つけました。共有する価値があると思った。

ほとんどの例readStreamsはファイルから作成します。しかし、私の場合、メッセージプールreadStreamからのJSON文字列から作成する必要があります。

var jsonStream = through2.obj(function(chunk, encoding, callback) {
                    this.push(JSON.stringify(chunk, null, 4) + '\n');
                    callback();
                });
// message.value --> value/text to write in write.txt 
jsonStream.write(JSON.parse(message.value));
var writeStream = sftp.createWriteStream("/path/to/write/write.txt");

//"close" event didn't work for me!
writeStream.on( 'close', function () {
    console.log( "- done!" );
    sftp.end();
    }
);

//"finish" event didn't work for me either!
writeStream.on( 'close', function () {
    console.log( "- done!"
        sftp.end();
        }
);

// finally this worked for me!
jsonStream.on('data', function(data) {
    var toString = Object.prototype.toString.call(data);
    console.log('type of data:', toString);
    console.log( "- file transferred" );
});

jsonStream.pipe( writeStream );

「finish」をリッスンする代わりに、「close」の2つのハンドラーがあります。おそらくそれが理由でした。「finish」イベントは私にとってはうまくいきます。
— jowo 2017年

3

次に、リクエストのエラーを処理し、ファイルが書き込まれた後にコールバックを呼び出すソリューションを示します。

request(opts)
    .on('error', function(err){ return callback(err)})
    .pipe(fs.createWriteStream(filename))
    .on('finish', function (err) {
        return callback(err);
    });
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.