LoginSignup
4
4

More than 5 years have passed since last update.

Stream2関連でEvent: 'data'を書いた時のEvent: 'readable'、 'finish' の動作確認

Last updated at Posted at 2013-01-02

--注意:これは、Stream2の正しい使い方ではなくて、新旧混ぜた時にv0.9.5でどう動くのか?というテストです--

v0.9.4 から Stream2 が実装されてるのでちょっとテスト。

まず、参考ページを見る:
Api changes between v0.8 and v0.10 
https://github.com/joyent/node/wiki/Api-changes-between-v0.8-and-v0.10
Stream
https://github.com/joyent/node/blob/master/doc/api/stream.markdown

・ 'data'イベントハンドラを追加するか、pause() またはresume() を呼ぶと、 (自動的に) "旧モード"に切り替わります。

で、これ読んで、てっきり、on('data', fn) を書けば、v0.9.4 で新しく追加された Event: 'readable' や v0.9.5 で追加された Event: 'finish' は動かないのかな?と思ったら、そんなことはなかった。

var spawn = require('child_process').spawn;
// `ls -ln 現在のディレクトリ` を実行する
var child = spawn('ls', ['-ln', __dirname]);
// イベント
child.stdout.on('readable', function () {
  console.log('on readable');
});
child.stdout.on('finish', function () {
  console.log('on finish');
});
child.stdout.on('data', function (data) {
  console.log('on data: ' + data);
});

結果は、こうなります

on data: total 4
-rw-r--r-- 1 1005 1005    0  1月  1 16:10 a.txt
-rw-r--r-- 1 1005 1005    0  1月  1 16:10 b.txt
-rw-r--r-- 1 1005 1005 1497  1月  2 10:12 demo-s2.js

on readable
on finish

動いてます。で、'data' より 'readable' が遅い。これで良いのだろうか?

HTTPも試してみます。まず、旧来のやつ。

var http = require('http');

// Webサーバー起動 port 3000
var server = http.createServer(function(req, res) {

  res.writeHead(200, {
    'Content-Type': 'text/html; charset=utf-8'
  });
  res.write('hi');
  res.end('(^0^)/'); //クライアントへ出力する
}).listen(3000, function() {

  // 上のサーバーに向けて テスト用クライアントを実行する
  http.get({port: 3000}, function(res) {

    res.on('data', function(data) {
      console.log('--on dataで:'+data+'--');
    });

    res.on('end', function() {
      server.close(); // 受信したらテストなので終了
    });
  });
});

結果はこうです

--on dataで:hi--
--on dataで:(^0^)/--

次に、 on data をやめてみる。

var http = require('http');

// Webサーバー起動 port 3000
var server = http.createServer(function(req, res) {

  res.writeHead(200, {
    'Content-Type': 'text/html; charset=utf-8'
  });
  res.write('hi');
  res.end('(^0^)/'); //クライアントへ出力する
}).listen(3000, function() {

  // 上のサーバーに向けて テスト用クライアントを実行する
  http.get({port: 3000}, function(res) {

    res.on('readable', function() {
      console.log('--on readableで:'+res.read()+'--');
    });

    res.on('end', function() {
      console.log('--on endで:'+res.read()+'--');
      server.close(); // 受信したらテストなので終了
    });
/*
    res.on('data', function(data) {
      console.log('--dataで:'+data+'--');
    });
*/

  });
});

こうなります

--on readableで:hi(^0^)/--
--on endで:null--

そして、上記コードのコメントアウト res.on('data' ... を外すと、
結果はこうなりました。

--on readableで:null--
--on readableで:hi--
--on readableで:(^0^)/--
--on endで:null--

あれ? on data きいてないね。試しに、 res.on('data' ...の順番を変えてみます。

var http = require('http');

// Webサーバー起動 port 3000
var server = http.createServer(function(req, res) {

  res.writeHead(200, {
    'Content-Type': 'text/html; charset=utf-8'
  });
  res.write('hi');
  res.end('(^0^)/'); //クライアントへ出力する
}).listen(3000, function() {

  // 上のサーバーに向けて テスト用クライアントを実行する
  http.get({port: 3000}, function(res) {

    res.on('data', function(data) {
      console.log('--dataで:'+data+'--');
    });

    res.on('readable', function() {
      console.log('--on readableで:'+res.read()+'--');
    });

    res.on('end', function() {
      console.log('--on endで:'+res.read()+'--');
      server.close(); // 受信したらテストなので終了
    });
  });
});

そしたら、こうなりました。

--dataで:hi--
--on readableで:null--
--dataで:(^0^)/--
--on readableで:null--
--on endで:null--

イベントdataが生きて、ローカル変数dataが死んでる。
上記イベントセットする順番は動作に関係するということかな。

で、ここで、最初のサンプルの on data の順番! と思うわけですよ。
で、試したけれど、同じ結果でした。。。

あとで、こんな感じのも試してみる

var Writable = require('stream').Writable;
var util = require('util');

// myWriterコンストラクタへ Writable を継承する
util.inherits(myWriter, Writable);

// myWriterコンストラクタ
function myWriter() {
  Writable.apply(this, arguments);
}
// コンソールへ出力する writeメソッド
myWriter.prototype.write = function (chunk, cb) {
  console.log(chunk.toString()); // コンソールへ出力
};


// chunk用のデータ配列
var chunks = ['1', '22', '333', '4444'];

// myWriter から インスタンス tw を作成する
var tw = new myWriter();

// 'finish'イベントをセット (chunksがなくなると発生)
tw.on('finish', function () {
  console.log('finishしました。');
});

// chunk用のデータ配列から順番に writeで出力
chunks.forEach(function (chunk) {
  tw.write('--' + chunk);    // コンソールへ出力
});

tw.end();

この結果は

--1
--22
--333
--4444
finishしました。

さて、どうなるでしょう?

4
4
4

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
4
4