1. 程式人生 > >Node.js快速入門

Node.js快速入門

Node讓你可以用javascript編寫伺服器端程式,讓javascript脫離web瀏覽器的限制,像C#、JAVA、Python等語言 一樣在伺服器端執行,這也讓一些熟悉Javascript的前端開發人員進軍到伺服器端開發提供了一個便利的途徑。 Node是基於Google的V8引擎封裝的,並提供了一些編寫伺服器程式的常用介面,例如檔案流的處理。Node的目的是提供一種簡單的途徑來編寫高性 能的網路程式。 (注:1、本文基於Node.js V0.3.6; 2、本文假設你瞭解JavaScript; 3、本文假設你瞭解MVC框架;4、本文示例原始碼:learnNode.zip)

Node.js的效能

hello world 測試:

300併發請求,返回不同大小的內容: 為什麼node有如此高的效能?看node的特性。

Node.js的特性

1. 單執行緒2. 非阻塞IO3. Google V84. 事件驅動

你好,世界

這,當然是俗套的Hello World啦(hello_world.js):

var http = require('http');

http.createServer(function(req, res){

    res.writeHead(200,{'Content-Type':'text/plain'});

    res.end('Hello World

\n');

}).listen(8124,"127.0.0.1");

console.log('Server running at http://127.0.0.1:8124/');

require類似於C#的using、Python的import,用於匯入模組(module)。node使用的是CommonJS的模組系 統。http.createServer 的引數為一個函式,每當有新的請求進來的時候,就會觸發這個函式。最後就是繫結要監聽的埠。

怎麼執行?

當然,是先安裝node.js啦。到http://nodejs.org/下載並編譯,支援Linux、Mac,也支援windows下的Cygwin。具體的安裝說明見:

http://howtonode.org/how-to-install-nodejs 裝好node後,就可以執行我們的hello world了:

$ node hello_world.js

Server running at http://127.0.0.1:8124/

程式設計習慣的改變?

我們來寫一個讀取檔案內容的指令碼:

//output_me.js

var fs = require('fs'), fileContent ='nothing';

fs.readFile(__filename,"utf-8",function(err, file){

if(err){

        console.log(err);

return;

}

    fileContent = file;

    console.log('end readfile \n');

});

console.log('doSomethingWithFile: '+ fileContent +'\n');

這個指令碼讀取當前檔案的內容並輸出。__filename是node的一個全域性變數,值為當前檔案的絕對路徑。我們執行這個指令碼看一下:

有沒發現結果不對呢?列印的fileContent並不是讀取到的檔案內容,而是初始化的時候賦值的nothing,並且‘end readfile’最後才打印出來。前面我們提到node的一個特性就是非阻塞IO,而readFile就是非同步非阻塞讀取檔案內容的,所以後面的程式碼並 不會等到檔案內容讀取完了再執行。請謹記node的非同步非阻塞IO特性。所以我們需要將上面的程式碼修改為如下就能正常工作了:

//output_me.js

var fs = require('fs'), fileContent ='nothing';

fs.readFile(__filename,"utf-8",function(err, file){

if(err){

        console.log(err);

return;

}

    fileContent = file;

//對於file的處理放到回撥函式這裡處理

    console.log('doSomethingWithFile: '+ fileContent +'\n');

});

console.log('我們先去喝杯茶\n');

寫個Web MVC框架試試

下面我們用node來寫一個小玩具:一個Web MVC框架。這個小玩具我稱它為n2Mvc,它的程式碼結構看起來大概如下:

和hello world一樣,我們需要一個http的伺服器來處理所有進來的請求:

var http = require('http'),

querystring = require("querystring");

exports.runServer=function(port){

    port = port ||8080;

var server = http.createServer(function(req, res){

var _postData ='';

//on用於新增一個監聽函式到一個特定的事件

        req.on('data',function(chunk)

{

            _postData += chunk;

})

        .on('end',function()

{

            req.post= querystring.parse(_postData);

            handlerRequest(req, res);

});

}).listen(port);

    console.log('Server running at http://127.0.0.1:'+ port +'/');

};

這裡定義了一個runServer的方法來啟動我們的n2Mvc的伺服器。有沒注意到runServer前面有個exports?這個 exports相當於C#中的publish,在用require匯入這個模組的時候,runServer可以被訪問到。我們寫一個指令碼來演示下node 的模組匯入系統:

//moduleExample.js

var myPrivate ='豔照,藏著';

exports.myPublish='冠西的相機';

this.myPublish2='this也可以哦';

console.log('moduleExample.js loaded \n');

執行結果:

從結果中我們可以看出exports和this下的變數在外部匯入模組後,可以被外部訪問到,而var定義的變數只能在指令碼內部訪問。 從結果我們還可以看出,第二次require匯入moduleExample模組的時候,並沒有列印“moduleExample.js loaded”,因為require匯入模組的時候,會先從require.cache 中檢查模組是否已經載入,如果沒有載入,才會從硬碟中查詢模組指令碼並載入。 require支援相對路徑查詢模組,例如上面程式碼中require(‘./moduleExample’)中的“./”就代表在當前目錄下查詢。如果不 是相當路徑,例如 require(‘http’),node則會到require.paths中去查詢,例如我的系統require.paths為:

當require(‘http’)的時候,node的查詢路徑為:

1/home/qleelulu/.node_modules/http

2/home/qleelulu/.node_modules/http.js

3/home/qleelulu/.node_modules/http.node

4/home/qleelulu/.node_modules/http/index.js

5/home/qleelulu/.node_modules/http/index.node

6/home/qleelulu/.node_libraries/http

7/home/qleelulu/.node_libraries/http.js

8、參考前面

再看回前面的程式碼,http.createServer中的回撥函式中的request註冊了兩個事件,前面提到過node的一個特點是事件驅動 的,所以這種事件繫結你會到處看到(想想jQuery的事件繫結?例如$(‘a’).click(fn))。關於node的事件我們在後面再細說。 request物件的data事件會在接收客戶端post上來的資料時候觸發,而end事件則會在最後觸發。所以我們在data事件裡面處理接收到的資料 (例如post過來的form表單資料),在end事件裡面通過handlerRequest 函式來統一處理所有的請求並分發給相應的controller action處理。 handlerRequest的程式碼如下:

var route = require('./route');

var handlerRequest =function(req, res){

//通過route來獲取controlleraction資訊

var actionInfo = route.getActionInfo(req.url, req.method);

//如果route中有匹配的action,則分發給對應的action

if(actionInfo.action){

//假設controller都放到當前目錄的controllers目錄裡面,還記得require是怎麼搜尋module的麼?

var controller = require('./controllers/'+actionInfo.controller);// ./controllers/blog

if(controller[actionInfo.action]){

var ct =new controllerContext(req, res);

//動態呼叫,動態語言就是方便啊

//通過applycontroller的上下文物件傳遞給action

            controller[actionInfo.action].apply(ct, actionInfo.args);

}else{

            handler500(req, res,'Error: controller "'+ actionInfo.controller+'" without action "'+ actionInfo.action+'"')

}

}else{

//如果route沒有匹配到,則當作靜態檔案處理

        staticFileServer(req, res);

}

};

這裡匯入來一個route模組,route根據請求的url等資訊去獲取獲取controller和action的資訊,如果獲取到,則通過動態呼叫呼叫action方法,如果沒有匹配的action資訊,則作為靜態檔案處理。 下面是route模組的程式碼:

var parseURL = require('url').parse;

//根據http請求的method來分別儲存route規則

var routes ={get:[], post:[], head:[], put:[],delete:[]};

/**

註冊route規則

示例:

* route.map({

*     method:'post',

*     url: /\/blog\/post\/(\d+)\/?$/i,

*     controller: 'blog',

*     action: 'showBlogPost'

* })

*/

exports.map=function(dict){

if(dict && dict.url&& dict.controller){

var method = dict.method? dict.method.toLowerCase():'get';

        routes[method].push({

            u: dict.url,//url匹配正則

            c: dict.controller,

            a: dict.action||'index'

});

}

};

exports.getActionInfo=function(url, method){

var r ={controller:null, action:null, args:null},

        method = method ? method.toLowerCase():'get',

// url: /blog/index?page=1 ,pathname: /blog/index

        pathname = parseURL(url).pathname;

var m_routes = routes[method];

for(var i in m_routes){

//正則匹配

        r.args= m_routes[i].u.exec(pathname);

if(r.args){

            r.controller= m_routes[i].c;

            r.action= m_routes[i].a;

            r.args.shift();//第一個值為匹配到的整個url,去掉

break;

}

}

//如果匹配到router大概是 {controller:'blog', action:'index', args:['1']}

return r;

};

map方法用於註冊路由規則,我們新建一個config.js的檔案,來配置route規則:

//config.js

var route = require('./route');

route.map({

    method:'get',

    url:/\/blog\/?$/i,

    controller:'blog',

    action:'index'

});

如果請求的url有匹配的route規則,則會返回controller和action資訊。例如上面的route配置,當訪問 /blog 這個url的時候,則會呼叫 ./controllers/blog.js 模組裡面的index函式。 當呼叫action的時候,會傳遞controllerContext給acation:

var ct =new controllerContext(req, res);

//動態呼叫,動態語言就是方便啊

//通過applycontroller的上下文物件傳遞給action

            controller[actionInfo.action]

相關推薦

Node.js快速入門

Node讓你可以用javascript編寫伺服器端程式,讓javascript脫離web瀏覽器的限制,像C#、JAVA、Python等語言 一樣在伺服器端執行,這也讓一些熟悉Javascript的前端開發人員進軍到伺服器端開發提供了一個便利的途徑。 Node是基於Google的V8引擎封裝的,並提供了

Vue.js快速入門

Vue.js Vue.js快速入門 Vue.js簡介 了解Vue.js Vue.js是一個輕巧、高性能、可組件化的MVVM庫,同時擁有非常容易上手的API。Vue.js 的目標是通過盡可能簡單的 API 實現響應的數據綁定和組合的視圖組件,它不僅易於上手,還便於與第三方庫或既有項目整合. Vue.js

Node.js學習筆記(1):Node.js快速開始

path 文本文 下載 啟動程序 直接 查看 學習筆記 完成後 編輯器 Node.js學習筆記(1):Node.js快速開始 Node.js的安裝 下載 官方網址:https://nodejs.org/en/ 說明:   在Windows上安裝時務必選擇全部組件,包括勾選

node.js--初步入門使用

pat 讀取文件 add 對象 doc form function meta ner 1.Hello World   var http=require(‘http‘);  //創建服務器  var server=http.createServer(function(req,

doodoo.js快速入門教程?

node Doodoo.js -- 中文最佳實踐Node.js Web快速開發框架。支持Koa.js, Express.js中間件,支持模塊化,插件,鉤子機制,可以直接在項目裏使用 ES6/7(Generator Function, Class, Async & Await)等特性 htt

doodoo.js快速入門教程

touch es6 odoo node 框架 創建 init fun http Doodoo.js -- 中文最佳實踐Node.js Web快速開發框架。支持Koa.js, Express.js中間件,支持模塊化,插件,鉤子機制,可以直接在項目裏使用 ES6/7(Gener

node.js入門到放棄(二)

簡單的 all == ons true nts 數值 定時 註冊 上章講了學習node,應該去學習什麽,對這些框架去進行學習現在咋們聊聊如何用原生來進行操作 主要來講一下events-事件觸發器 先來講一個簡單的實例 EventEmitter的實例,綁定一個監聽器。用

node.js入門到放棄(一)

主鍵 data timestamp insert 代碼 了解 javascrip ice where 以下內容全是我個人理解寫出,如有不對,請立刻練習本人進行更改。以免被剛入門的被我帶入坑裏。 —node是什麽?我想大家應該都知道。 node是前端未來幹掉後

Node.js入門到實戰ECMAScript6一頁紙總結(很大的一頁紙)

轉載:30分鐘掌握ES6/ES2015核心內容(上) 轉載:30分鐘掌握ES6/ES2015核心內容(下) 轉載:ECMAScript 6 入門 一、ES5/ES6和babel ECMAScript5,即ES5,是ECMAScript的第五次修訂,於2009年完成標準化,現在的瀏覽器已經相當於完全實現了這個標

【全開源+免費更新】doodoo.js快速入門教程

簡介 ​ Doodoo.js -- 中文最佳實踐Node.js快速開發框架。支援Koa.js, Express.js中介軟體,支援模組機制,外掛機制,鉤子機制,讓開發 Node.js 專案更加簡單、高效、靈活。   特性 支援koa全部中介軟體 支援使用 ES6

Node.js 快速開發出多功能的多人線上的文章分享平臺

最近在學習使用 Node.js 框架,邊學習邊使用,花了大概 3周 時間做完這個 Web應用 且在 12月16 凌晨左右上線成功(其實就是把開發環境搬到伺服器), 地址: a.lishaoy.net 這個 Web應用 的程式碼是開源的,如對這個應用感興趣,想知道程式碼是如何執行的,可以去我 GitHub 下

Node js開發入門 使用cookie保持登入

                     這次來做一個網站登入的小例子,後面會用到。這個示例會用到Cookie、HTML表單、POST資料體(body)解析。第一個版本,我們的使用者資料就寫死在js檔案裡。第二個版本會引入MongoDB來儲存使用者資料。示例準備1. 使用express建立應用就下面的命令序列

Node.js開發入門——MongoDB與Mongoose

為了儲存網站的使用者資料和業務資料,通常需要一個數據庫。MongoDB和Node.js特別般配,因為MongoDB是基於文件的非關係型資料庫,文件是按BSON(JSON的輕量化二進位制格式)儲存的,增刪改查等管理資料庫的命令和JavaScript語法很像。如果你

Node.js入門到實戰(六)React一頁紙總結(很大的一頁紙)

一、React React是一個JavaScript庫,是由FaceBook和Instagram開發的,主要用於使用者建立圖形化介面。 由於 React 的設計思想極其獨特,屬於革命性創新,效能出眾,程式碼邏輯卻非常簡單。所以,越來越多的人開始關注和使用,認為它可能是

Node.js入門到實戰(七)Solr查詢規則總結

一、Solr Solr是一個獨立的企業級搜尋應用伺服器,它對外提供類似於Web-service的API介面。使用者可以通過http請求,向搜尋引擎伺服器提交一定格式的XML檔案,生成索引;也可以通過Http Get操作提出查詢請求,並得到XML格式的返回結果。 本文不涉及

Node.js入門到實戰(八)Solr的層級

參考:Node.js從入門到實戰(七)Solr查詢規則總結 一、Solr的層級 Solr作為關鍵的搜尋元件,在整個系統中的架構如下圖所示: Solr的索引服務是為了提高搜尋的效率,一般而言Solr需要配合Nosql DB使用,作為與NoSQL DB相互獨立的補充,在能夠

Node.js入門到實戰(五)ECMAScript6一頁紙總結(很大的一頁紙)

一、ES5/ES6和babel ECMAScript5,即ES5,是ECMAScript的第五次修訂,於2009年完成標準化,現在的瀏覽器已經相當於完全實現了這個標準。 ECMAScript6,即ES6,也稱ES2015,是ECMAScript的第六次修訂,於2015

Node.js入門到實戰(四)Node.js / JavaScript / ECMAScript的關係

一、Node.js Node.js 是一個基於 Chrome V8 引擎的 JavaScript 執行環境。 Node.js 使用了一個事件驅動、非阻塞式 I/O 的模型,使其輕量又高效。 Node.js 的包管理器 npm,是全球最大的開源庫生態系統。 V8引擎本身使用

Node.js入門到實戰(一)Intellj Idea 2017下的第一個Node.js工程

參考: 一、Intellj Idea下的初始工程 使用Idea建立的Node.js Express工程建立成功後執行, 二、程式碼分析 第一個工程命名為PageIron,該專案的主要程式碼位於PageIron/bin/www檔案中: Node.js 應用的組成部分:

Node.js入門到實戰(三)Npm使用介紹

一、NPM NPM是隨同NodeJS一起安裝的包管理工具,能解決NodeJS程式碼部署上的很多問題,常見的使用場景有以下幾種: 允許使用者從NPM伺服器下載別人編寫的第三方包到本地使用。允許使用者從NPM伺服器下載並安裝別人編寫的命令列程式到本地使用。允許使用者將自己編寫