眞鍋です。
スミマセン。誤解してました。
以下のファイルを書いて試したところ、fs.createReadStream だと
readable イベントは発火しませんでした。
---- (ここから)
var util = require('util');
var fs = require('fs');
var f = __filename;
var s = fs.createReadStream(f, {bufferSize: 128 }); // default : 64 * 1024
[byte]
s.on( 'readable', function(){ util.puts( 'readable', arguments ) } );//発火せず
s.on( 'open', function(){
util.puts( 'open', arguments )
// data イベントはopen後でも追加できる。
s.on('data', function( d ){ util.puts('DATA ', d) })
} );
s.on( 'error', function(){ util.puts( 'error', arguments ) } );
s.on( 'close', function(){ util.puts( 'close', arguments ) } );
---- (ここまで)
実は、readable イベントに押し込めるのではないかと考えていましたが、
「data イベントは open 直後に実行されるハンドラ内に定義しても良い」と確認できます。
てことで、「fs.stat() も open イベント内部に押し込むと、意図した順序で処理してくれる。」てのが課題に対する私の解答。
Nodeを始めた頃「関数のネスト(ピラミッドとも)で書く特徴」に悩まされました。
理解が深まってくると、ピラミッドをフラットで見やすく書く為の
「フロー制御」を考えたくなると思います。
2013年4月16日 7:08 aporo4000 <[email protected]>:
> 全然違うかもしれませんが、最初に読み込むバイト数を指定するとか!?ですか?
>
> 2013年4月16日火曜日 1時20分00秒 UTC+9 koichik:
>>
>> 小林 (koichik) です.
>>
>> 勝手に課題シリーズ第二弾w
>> 前のメールでも書いたように、非同期 API では
>>
>> ... //(1)
>> foo(hoge, function(err) {
>> ... //(2)
>> });
>> ... //(3)
>>
>> の場合の処理順は (1)->(3)->(2) となります。
>>
>> 問題のコードは HTTP を処理するリスナの中に
>> あるので、
>>
>> http.createServer(function(req, res) {
>> ... //(1)
>> foo(hoge, function(err) {
>> ... //(2)
>> });
>> ... //(3)
>> });
>>
>> となるわけですが、ここで二つの HTTP リクエスト、
>> A と B がほとんど同時に (ただし A が先に) 到着した
>> 場合の処理順を考えてみましょう。
>>
>> その場合は、
>> A(1)->A(3)->A(2)->B(1)->B(3)->B(2) となる。。。
>> 保証はなくて、
>>
>> A(1)->A(3)->B(1)->B(3)->A(2)->B(2) だったり
>> A(1)->A(3)->B(1)->B(3)->B(2)->A(2) だったり
>> する可能性もあります。
>> リクエスト A に関する処理が全て完了してから
>> リクエスト B の処理が開始されるとは限らない
>> わけです。
>>
>> さて、問題のコードからキャッシュの処理に着目すると、
>>
>> http.createServer(function (request, response) {
>> //(1)
>> if(cache[f]) {
>> response.writeHead(200, headers);
>> response.end(cache[f].content);
>> return;
>> }
>>
>> fs.stat(f, function(err, stats) {
>> //(2)
>> var bufferOffset = 0;
>> cache[f] = {content: new Buffer(stats.size)};
>> s.on('data', function(data) {
>> //(3)
>> data.copy(cache[f].content, bufferOffset);
>> bufferOffset += data.length;
>> });
>> });
>> }).listen(8080);
>>
>> という構造を抽出できるのですが、最初に到着した
>> リクエスト A の処理では、
>>
>> (1) キャッシュが存在しないことを確認し、
>> (2) キャッシュを作成して fs.stat() を呼び出し、
>> (3) 'data' イベントが発生するとキャッシュの中身を設定
>>
>> と流れていくことはもう理解できているかと思います。
>>
>> では、この途中のどこかで別のリクエスト B が到着すると
>> どうなるでしょうか?
>>
>> A(1)->A(2)->A(3)
>>
>> と進む途中のどこかで、リクエスト B の処理が
>> 挟まってきた場合を考えてみましょう。
>>
>> A(1)->B(1)->?
>>
>> とか、
>>
>> A(1)->A(2)->B(1)->?
>>
>> とか、タイミングによっては B の処理が進む経路も
>> 変わってくるはずですね。
>>
>> 掲載されたコードはどんな場合でも正しく
>> 動作するでしょうか?
>> うまくいかないのはどんな場合?
>> どんな場合でもうまく動くようにするに
>> どうしたらいいでしょうか?
>>
>>
>> On Mon, 15 Apr 2013 06:18:31 -0700 (PDT), aporo4000 <[email protected]>
>> wrote:
>>
>> > いまちょうどそれを勉強してる初心者なので、みなさんみたいにスラスラ書いたり出来るように頑張ります!
>> >
>> > --
>> >
>> > ---
>> > このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。
>> > このグループから退会し、メールの受信を停止するには、[email protected]にメールを送信します。
>> > その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。
>> >
>>
>>
>> --
>> {
>> name: "Koichi Kobayashi",
>> mail: "[email protected]",
>> blog: "http://d.hatena.ne.jp/koichik/",
>> twitter: "@koichik"
>> }
>>
>> --
>
> ---
> このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。
> このグループから退会し、メールの受信を停止するには、[email protected]にメールを送信します。
> その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。
>
>
>
--
---
このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。
このグループから退会し、メールの受信を停止するには、[email protected] にメールを送信します。
その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。