質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

2528閲覧

【Node.js/NodeSchool/learnyounode】bl(BufferList)の動きがよく分からない

afroscript

総合スコア148

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2016/09/10 07:12

編集2016/09/10 07:21

#概要

Webプログラミング初心者です。

現在、NodeSchoolのworkshopper、「learnyounode」を用いてNode.jsの勉強中をしております。

その8問目についての質問です。

「Webからhttpリクエストでデータをとってて、そのデータの文字数と、データそのものを表示する」というコード書く問題なのですが、
自分で書いてみた答えと正式な回答で結果にズレが生じ、その原因がよく分かりません。。。

※おそらく僕が模範回答で使われているパッケージ「bl」に関して、どのようなことを実現できるものか、イマイチ理解できていないからだと思います。。。

下記に

  1. learnyounodeの問題
  2. 自分の書いたコード
  3. 模範回答
  4. learnyounode verify(答え合わせ)してみた結果

を記載しますので、なぜ結果に違いがでているのか、どなたかご教示いただけますと幸いです。

#1. learnyounoeの問題

## HTTP 集める (13問中8問目) 1つ目のコマンドライン引数は URL 文字列です。 そのURL文字列を使ってHTTP のデーターをロード (※)するアプリを書いてください。 サーバから全て(最初のイベントだけではなく)のデータを集め、次の2行をコン ソールに出力して下さい。 1行目は文字数です。2行目はサーバから受け取った全てのデータを文字列で出力し てください。 ───────────────────────────────────────────────────────────────────────────── ## ヒント 2つの方法があります: 1) 全ての data イベントの結果をまとめて end イベントの時に書き出してください。 2) サードパーティ製のパッケージを使っても良いです。以下の2つのパッケージはこ の問題に関して役に立ちます。 bl (Buffer List) か concat-streamのいずれかを選んでください。 <http://npm.im/bl> <http://npm.im/concat-stream> Node.js のパッケージをインストールするために Node.js のパッケージ管理ツールである npmを使ってください。 コマンドラインに次のコマンドを書いてください: $ npm install bl 上記のコマンド実行すると、指定されたパッケージの一番新しいバーションをダウ ンロードして node_modules という新しいフォルダに格納します。 そのフォルダにあるパッケージは require を使って . の接頭辞なしで利用できます: var bl = require('bl') メモ: Node.js のロードの優先順位は、まずNode.jsのコア、その後は上述の node_modulesのフォルダの順です。 インターネットに接続できない場合には node_modules にfile:///Users/usaqwako/.nvm/versions/node/v4.1.2/lib/node_modules/learny ounode/node_modulesのフォルダのパッケージをコピーしてください: file:///Users/usaqwako/.nvm/versions/node/v4.1.2/lib/node_modules/learnyou node/node_modules/bl file:///Users/usaqwako/.nvm/versions/node/v4.1.2/lib/node_modules/learnyou node/node_modules/concat-stream bl も concat-stream も Stream を入力として pipe (※) することができます。次の例ではStream が終わってからコールバックが呼ばれています: ※ pipe: Stream中に流れるデータを次々と橋渡しする関数を登録すること。 response.pipe(bl(function (err, data) { /* ... */ })) // or response.pipe(concatStream(function (data) { /* ... */ })) メモ:もしかしたら Buffer から data.toString() をつかって文字列に変換する必要があるかもしれません。 モジュールのドキュメントは learnyounode と一緒にインストールされているため、このリンクをブラウザで見てください: file:///Users/usaqwako/.nvm/versions/node/v4.1.2/lib/node_modules/learnyou node/docs/bl.html file:///Users/usaqwako/.nvm/versions/node/v4.1.2/lib/node_modules/learnyou node/docs/concat-stream.html ───────────────────────────────────────────────────────────────────────────── » この説明をもう一度表示する: learnyounode print » 作成したアプリをテスト環境で実行する: learnyounode run program.js » 作成したアプリが正しいか検証する: learnyounode verify program.js » 出力結果が見づらい場合には --no-color をつけてみてください: learnyounode verify program.js --no-color » ヘルプを表示する: learnyounode help

#2. 自分が書いたコード
ヒントにあったblは使わずに、下記のようにコードを書きました。
※この問題の前の問題、問7のコードを参考に書き換えて下記のように書いてみました。

JavaScript

1var http = require('http') 2 3http.get(process.argv[2], function(res){ 4 var data_all = [] 5 6 res.on("data", function(data){ 7 data_all.push(data) 8 }) 9 res.on("error", function(err){ 10 console.log(err) 11 }) 12 res.on("end", function(d){ 13 console.log(data_all.toString().length) 14 console.log(data_all.toString()) 15 }) 16 17}).on('error', console.error)

#3. 模範回答

正式な回答では、blというパッケージを使って以下のように書かれています。

JavaScript

1var http = require('http') 2var bl = require('bl') 3 4http.get(process.argv[2], function (response) { 5 response.pipe(bl(function (err, data) { 6 if (err) 7 return console.error(err) 8 data = data.toString() 9 console.log(data.length) 10 console.log(data) 11 })) 12})

特に

response.pipe(bl(function (err, data) {

ここ↑付近が、イマイチ何をしようとしてるか分からないです。。。

#4. learnyounode verify(答え合わせ)してみた結果

あなたの回答の評価結果(想定回答との比較結果): ──────────────────────────────────────────────────────────────────────────────── 1. 回答内容: "319" 1. 想定回答: "270" 2. 回答内容: "Lets ,get ,some ,nipper ,no ,dramas ,she'll ,be ,right ,flick. ,It'll ,be ,kindie ,bloody ,lets ,throw ,a ,your ,shout." 2. 想定回答: "Lets get some nipper no dramas she'll be right flick. It'll be kindie bloody lets throw a your shout." 3. 回答内容: "Grab ,us ,a ,dero ,no ,worries ,she'll ,be ,right ,dinky-di. ,Stands ,out ,like ,a ,chuck ,a ,yewy ,bloody ,as ,cunning ,as ,a ,rubbish. ,Gutful ,of ,boogie ,board ,heaps ,she'll ,be ,right ,cockie. " 3. 想定回答: "Grab us a dero no worries she'll be right dinky-di. Stands out like a chuck a yewy bloody as cunning as a rubbish. Gutful of boogie board heaps she'll be right cockie. " 4. 回答内容: "" 4. 想定回答: "" ──────────────────────────────────────────────────────────────────────────────── ✗ 回答内容は想定回答とマッチしませんでした! # 残念! 「HTTP 集める」に対するあなたの回答は不合格でした。再度挑戦してみて下さい!

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

答えが不正解になった理由はdata_all.toString()で配列の要素をカンマで区切った文字列を生成しているからで、これを区切り文字無しで結合する必要があります。
data_all.join('')(この join は遅いらしいですが)で結合すれば、正解になるのではないでしょうか。

response.pipe(bl(function (err, data)

response.pipe は、大きなデータが流れる場合に次々にデータを送っていくことで、メモリを節約したり、並列度をあげたりしたい時に使うものです。しかし、このコードでは、 bl のコンストラクタに渡した関数が pipe から end が呼ばれてから動作するので性能的な意味がありません。全部バッファに溜めてから処理しているので、afroscript.10さんが書かれたコードと大差ありません。しいて言うなら少しコードが短いということでしょうか。

気にする必要はないと思います。 response.pipe っていうのがあるんだ、というのは覚えておくと良いかもです。

投稿2016/09/10 08:11

mit0223

総合スコア3401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

afroscript

2016/09/10 08:28 編集

ご指摘頂いた通り、data_all.toString()をdata_all.join('')に変更することで解決しました! 出力データに「,」が入っていたのはarray.toString()が原因だったのですね…! また、response.pipeの解説もありがとうございます! ヒントにあったので、なにかしら使わなければいけない理由があるのかtお思っておりました。 これでやっと次に進めます!ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問