LoginSignup
1
1

More than 5 years have passed since last update.

Node の stream を理解する その1

Posted at

今日は、Node の Stream をちゃんと理解したいと思ったので、いくつか試してみた。

stream-handbookを流している。ちょっと、今まで私がやってきた言語と違う雰囲気なので、ゆっくり理解したい。

pipe

Node の Stream は、unix のような pipe が使えるようす。

import * as http from 'http';
import * as fs from 'fs';
var oppressor = require('oppressor');

let server = http.createServer(function (req, res) {
    let stream = fs.createReadStream(__dirname + '/server.ts');
    stream.pipe(oppressor(req)).pipe(res);
});
server.listen(8000);

これっを実行すると、8000ポートでサーバが起動されて、このファイル自体を結果として返す。その際、oppressor という stream に対応したライブラリで、zip 圧縮をかけている。

gizpcompression.png

Google の開発ツールで見ると、しっかりgzip がかかっているのがわかる。

Readable

stream の Readable の、push メソッドで、Readable オブジェクトにデータを送ることができる。それをstdout にパイプして、出力している。

let Readable = require('stream').Readable;

namespace readable {

let rs = new Readable;
rs.push("hi ");
rs.push("Now I'm in Las Vegas\n");
rs.push(null);

rs.pipe(process.stdout);

}
hi Now I'm in Las Vegas

_read というメソッドを使うと、パイプ先から必要性があるときのみ、オンデマンドで、コールバックが呼ばれる

import {Readable} from 'stream';

namespace readable02 {
let rs = new Readable;

var c = 65 - 1;
rs._read = function () {
    if (c > 'Z'.charCodeAt(0)) rs.push(null);
    setTimeout(function() {
    rs.push(String.fromCharCode(++c));
    }, 100);
};

rs.pipe(process.stdout);


process.on('exit', function () {
    console.error('\n _read() called ' + (c - 65) + 'times');
});

process.stdout.on('error', process.exit);
}
$ node readable02.js | head -c4
ABCD
 _read() called 4times

ちなみに、タイムアウトを抜かすと、こんな感じになる。

$ node readable02.js | head -c4
ABCD
 _read() called 26times

結果は正しいのだが、最後の出力結果がおかしい。これは、どういうことかというと、 _read() はあくまでオンデマンドでコールされるの。最後の、process.stdout.on('error', process.exit); は、head -c4 で、4つのキャラクターを読んでその後不要になったら、SIGPIPE が発生するので、それを検出して、exit イベントを発生させて、それが、process.on('exit', ... で検出されてこれが表示される。
 ところが、OS から、SIGPIPE が来るまでのタイムラグがあるので、タイマーで待っている状態だ。

おまけ

さて、このプログラムをコンパイルする過程で、謎エラーに悩まされた。

$ tsc -p .
readable02.ts(1,5): error TS2451: Cannot redeclare block-scoped variable 'Readable'.
readble.ts(1,5): error TS2451: Cannot redeclare block-scoped variable 'Readable'.

tsファイルを見ても間違いが見つからず苦労したが、同じディレクトリにあるファイルがnamespace を切らずに、同じ定義をしたからだった。

ちなみに、何回typescript の環境構築しても、わすれてしまうので、メモしておく。

npm init
npm install -D typescript   // -D = --save-dev
tsc --init // typeconfig.json 作成
npm install @types/node --save-dev

今は、typings を使うことはいらない感じね。

まだまだ、Stream がまだまだので、少しづつ試してみる。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1