開始學習nodejs!javascript
參考書籍:The Node Beginner Book ,全部問題和討論都圍繞本書。html
1.學習nodejs須要具有的基礎知識:前端
js基本語法,基本上寫過前端的都能知足,原生js、jqueryjava
2.nodejs與基礎知識相比,學習的點在哪裏?node
nodejs自己就是js,以下:jquery
var http = require("http"); http.createServer(function(request, response) { response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World"); response.end(); }).listen(8888);
nodejs使用模塊化編程web
關於模塊化,只要知道它解決什麼問題便可:編程
模塊化其實就是封裝,把一組特定功能的代碼封裝在一個相似java jar包的模塊中,方便複用,使結構清晰,等等服務器
js從原生的順序無模塊代碼,到自執行函數、jquery匿名函數、到CommonJS,就是一個模塊化進程,習慣使用jquery的童鞋不該該抵觸新的模塊化編程app
nodejs的模塊化,咱們都要學習哪些?
1.使用現成模塊工具
如上代碼,copy到server.js中,cmd命令下執行 node server.js
訪問 http://localhost:8888/ ,一個簡單的web服務就成功訪問了!
這裏使用 require("http") 調用http模塊,這個是nodejs內置的
2.本身封裝模塊
server.js可能咱們會加入更多其餘的路由代碼,這時候咱們能夠把啓動功能遷移出去,如何辦?
var http = require("http"); function start() { function onRequest(request, response) { console.log("Request received."); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World"); response.end(); } http.createServer(onRequest).listen(8888); console.log("Server has started."); } exports.start = start;
server.js修改一下,把啓動web服務器的代碼移到start方法體中,
使用 exports.start = start 向外部暴露web啓動方法
習慣上,咱們使用index.js來啓動app,代碼以下:
var server = require("./server"); server.start();
執行 node index.js 效果同樣!
3.完善web服務器的路由功能
能夠發現,訪問8888的任意資源都會返回helloworld,why?
這就說明咱們這個服務器實際上是缺乏路由功能的,也能夠說,路由功能使用基本的if else便可實現,咱們先獲取request請求路徑
var http = require("http"); var url = require("url"); function start() { function onRequest(request, response) { var pathname = url.parse(request.url).pathname; console.log("Request for " + pathname + " received."); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World"); response.end(); } http.createServer(onRequest).listen(8888); console.log("Server has started."); } exports.start = start;
使用url便可獲取資源請求路徑。
習慣上,使用router.js來負責路由分發:
function route(pathname) { console.log("About to route a request for " + pathname); } exports.route = route;
server.js 導入route模塊, start方法調用route方法便可,
固然,route其實應該做爲服務器的一個組件傳入進去,咱們能夠這樣:
var http = require("http"); var url = require("url"); function start(route) { function onRequest(request, response) { var pathname = url.parse(request.url).pathname; console.log("Request for " + pathname + " received."); route(pathname); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World"); response.end(); } http.createServer(onRequest).listen(8888); console.log("Server has started."); } exports.start = start;
而index.js相應的:
var server = require("./server"); var router = require("./router"); server.start(router.route);
事實上,咱們如今的路由器還未有任何處理請求的功能,而根據經驗,處理各類請求,應該有對應的程序塊,
若是在rout方法體中使用if else,那麼代碼結構將會極其醜陋
js的函數式編程給了咱們一個啓示——能夠將不一樣的請求封裝在一個requestHandler中,而後暴露出來供route調用:
requestHandlers.js
function start() { console.log("Request handler 'start' was called."); } function upload() { console.log("Request handler 'upload' was called."); } exports.start = start; exports.upload = upload;
index.js入口腳原本載入handler
var server = require("./server"); var router = require("./router"); var requestHandlers = require("./requestHandlers"); var handle = {} handle["/"] = requestHandlers.start; handle["/start"] = requestHandlers.start; handle["/upload"] = requestHandlers.upload; server.start(router.route, handle);
handler就是一個字典,針對不一樣請求,執行不一樣的處理邏輯
相應改變的,server.js
var http = require("http"); var url = require("url"); function start(route, handle) { function onRequest(request, response) { var pathname = url.parse(request.url).pathname; console.log("Request for " + pathname + " received."); route(handle, pathname); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World"); response.end(); } http.createServer(onRequest).listen(8888); console.log("Server has started."); } exports.start = start;
router.js
function route(handle, pathname) { console.log("About to route a request for " + pathname); if (typeof handle[pathname] === 'function') { handle[pathname](); } else { console.log("No request handler found for " + pathname); } } exports.route = route;
至此,一個簡單的路由功能就優雅的實現了!
路由功能實現了,可是每一個請求響應全都是hello world,這個處理起來也不復雜,只須要讓handler返回結果,而後response將結果輸出出去便可!