[[FrontPage]] *承前 [#x67fd7d1] -単に実装したいだけなのに、一種のパズルを解く必要があるのはおかしいと思うんですよ。 *概要 [#lb1f60be] -通常、JavaScriptはユーザーのブラウザで動作するプログラミング言語ですが、Node.jsはサーバー側で動作するJavaScript -最近のトレンドである「イベントループ」による非同期・シングルスレッド処理を実現している *目次 [#td43bbd1] #contents *参考資料 [#u8c91d47] -[[僕が作ったサンプル(node v.9.8.0)>https://github.com/hamko/sample/blob/master/node/sample.js]] -[[非同期関数でDAGネットワークを構成する>https://qiita.com/hamko/items/2260adfa57fbce3ba09a]] *バージョン管理 [#ge5893e9] -必ずnvm, npmを利用してバージョンを管理を行う! -パッケージのバージョンアップ --たとえばmocha npm info mocha versions sudo npm install mocha@5.0.5 # 一旦ターミナルを閉じる *文法の議論 [#m842c98b] **async/await [#nd1a819a] -非同期関数での結果は、メインの方に一切渡らない。データも例外も --特に例外をメインの方に流すのは配列外参照レベルのバグなので注意。 -無名async/await関数というものもある **var/let/const [#v1d9ade2] -定義位置の「巻き上げ」 --どこに定義したとしても、スコープの一番上で定義したものとみなされる -違い --var: 関数ブロックでの変数(不自然) --let: ブロックでの変数(C++っぽいね) --const: ブロックでの再代入不可変数(C++っぽいね) -varは使わない(使う意味がないので) --理由:「関数ブロックの」変数となり、極めて不自然なので -なるべく全部const, 無理ならletという運用が自然 --forのイテレータとかにもlet *古い情報 [#d7d6a1a7] ++http ++fs: ファイル読み込みなど ++util: util.print("hoge")などが可能.console.log("hoge")と変わらない? -require("http") --HTTPモジュールを作る(オブジェクト指向みたいのもの) -コメントは//と/**/ -fs.readFileは非同期ファイル読み込み.全ての{}内部の処理が終わってから処理される(キューの処理を順に呼び出すためらしい.) -http.createServer(function(req, res){})は,server=http.createServer();server.on("request", function(req, res){});と同義 -http.createServer(function(req, res){A;B;})は,server=http.createServer();server.on("request", function(req, res){A;});server.on("request", function(req, res){B;});と同義 -A.jsでexports.IP="localhost";と書かれていると,B.jsでA=request("A.js");A.IP;によってアクセスできる. -構造体は,var setting = {"IP": "192.168.255.255", "PORT": 80};によってsetting.IPにアクセスできる -requireする前に,try{path=require.resolve("A.js"); var setting = require(path);} catch (e) {var setting = {"a": "hoge"}}とすると,jsファイルの存在確認ができる -forEachは,Arrayの簡易的なfor.indexとarは省略可能.var a=[1,2,3,4,5];a.forEach(function(val,index,ar){}); -Object.keys(Array),オブジェクトのキー部分の配列を取得することができる. -req.headersは,hostとかconnectionとかをキーとした配列 -urlはファイル構造ではなく,if (req.url === "/") {res.write("トップページです。");}else if (req.url === "/test") {res.write("実験用ページです。")}else {res.write("404");}のように分岐させる -URLに引数などがある場合は,req.urlではなく,var parsedUrl = url.parse("http://" + setting.IP + ":" + setting.PORT + req.url);parsedUrl.pathnameを代わりに使う -レスポンスのボディを送信.res.write("<html><body>テストデータです</body></html>");これがソースコードになる -Node.jsは非常にバージョン依存性が高いので,nvmで切り替えられるようにしておく --[[nvmのインストール,使い方>http://qiita.com/strsk/items/925644e124efcc964625]] -''npmのインストール後は必ず"npm install"を行う!'' --依存関係のものを何故かインストールしてくれないので. -野良でNode.jsをインストールしないこと.かならずnvmを介して. -JSの文法 var arr = ["a", "b", "c", "d", "e"]; for (i = 0; i < arr.length; i++) { document.write(arr[i] + '<br>'); } -サーバ側が受けるイベントは,connection, disconnectionがある. -クライアント側が受けるイベントは,任意である(serverがsocket.emit("myEvent", "hoge")とかemit("myEvent", {message: "", eventName: "myEvent"})などできるので) --emit:クライアント全てに送信,broadcast:自分含めて送信,volatile:クライアントが受け取らなくても良い -クライアント側のon("myEvent", function(data, func){})で,funcに書きこまれた関数がサーバ側で実行される! -req.on("readable", ...)はなぜか動かない.(018の一行掲示板をきちんと動くようにしました) /* req.on("readable", function () { req.data += req.read(); }); */ req.on('data', function (data) { req.data += data; }); -ejs --<% %>を使うときには、このように「処理部分だけを<% %>内に書き、出力は<%= %>に書く」というように、処理と出力をきちんと切り分けて考える必要がある、ということを忘れないようにしましょう。 -setIntervalの変更はclearしてsetしなおす --if(timer) clearInterval(timer);timer=setInterval(function(){document.getElementById("test").innerHTML=c++;},t);} -''コールバックを設定する時,$(function() {};を忘れると当然全く動かないので注意'' *Stream [#r822b44a] -Node.js の Stream には 4 つの種類があります。 --ReadableStream: そこからデータが読み出せる(データ生成源のラッパー: file, socket, stdin etc) --WritableStream: そこにデータを書き込める(データ入力先のラッパー: file, socket, stdout etc) --TransferStream: 左から右に処理しながら流す(データの改変などを行う: 圧縮, 暗号化, パース etc) --DuplexStream: HTTP サーバのようにデータの送受信を両方になう: http server etc ---Transfer, Duplex は Readable と Writable の組み合わせでもあります。 -結局、ReadableStreamとWritableStreamの速度の違いが大きければ、中間のどこかのstrategyでデータの速度を調整するためにback pressureを書ける必要がある。これは、strategyというプロパティが管理戦略として定義できる。 |