摘要:服務器每收到一條請求,都會用新的和對象觸發請求回調函數。在調用完請求回調函數之后,就要由你負責用方法結束響應。
前言
本文將介紹Node.js的一些基本概念,包含它的歷史,特性和簡單的使用等。如果你有過服務端的編程經驗,那么你將能很快熟悉它。
Node.js是什么這是Node.js官網上對其的定義,就是說,Node.js是一個javascript運行平臺,該平臺基于chrome v8 引擎。V8讓Node.js在性能上得到了巨大的提升,因為它去掉了中間環節,執行的不是字節碼,用的也不是解釋器,而是直接編譯成了本地機器碼。(注意:v8 5.9 發布后,Ignition 字節碼解釋器將默認啟動,v8 又回到了字節碼的懷抱,具體請參閱:https://cnodejs.org/topic/590...)
Node.js帶來的好處對一名前端而言,Node無疑有如下幾個好處:
開發人員用一種語言就能編寫整個Web應用,這可以減少開發客戶端和服務端時所需的語言切換。
有些NoSQL數據庫中用的就是JavaScript語言,(比如CouchDB和MongoDB),所以跟它們配合使用非常方便。
Node用的虛擬機(V8)會緊跟ECMAScript標準。換句話說,在Node中如果想用新的JavaScript語言特性,不用等到所有瀏覽器都支持。
特點Node.js采用的是事件驅動、非阻塞I/O的設計模型。大家想到了什么?這和javascript在瀏覽器上的運行機制是一樣的。
另外,對于高并發的處理,傳統平臺采用的是多線程方案,而Node.js則采用的是單線程、事件驅動、非阻塞I/O的設計模型。
我們來看一個瀏覽器中的例子:
$.post("/resource.json", function (data) { console.log(data) }) // 繼續執行
上面代碼是瀏覽器中的一個ajax請求,假如該請求需要耗費600ms,該ajax請求會在事件輪詢的外面執行(腳本執行的主順序之外),然后當這個ajax請求完成時(600ms后),它會發出一個“事件”,會有一個函數(通常稱作“回調”)來處理它。
這個操作是異步的,并不會“阻塞”腳本執行,事件輪詢仍然可以響應頁面上執行的其他交互或請求。這樣,瀏覽器可以對客戶做出響應,并且可以處理頁面上的很多交互動作。
我們再來看一個服務器中的例子:
// 數據庫查詢操作 db.query("SELECT * FORM work", function (data) { console.log(data) } )
這段代碼做了些I/O操作,并且在所有數據回來之前,這個進程并不會被阻塞。在Node中,I/O幾乎總是在主事件輪詢之外進行,使得服務器可以一直處于高效并且隨時能夠做出響應的狀態,就像NGINX(帶有異步I/O的事件輪詢的一種http服務器)一樣。這樣進程不會受I/O限制,因為I/O延遲不會拖垮服務器。因此一些在服務器上曾經是重量級的操作,在Node服務器上仍然可以是輕量級的。
dirt程序Node所針對的應用程序有一個專門的簡稱:DIRT。它表示數據密集型實時(data-intensive real-time)程序。上面已經提到,Node自身在I/O上非常輕量,能在處理大量請求時保持很多開放的連接,并且只占用一小部分內存,所以,它特別擅長處理數據密集型實時應用。比如在線文檔協作、對臨近公交車的實時精確定位,以及多人在線游戲等。
簡單的例子接下來我們先看一些簡單的例子。
文件操作var fs = require("fs") fs.readFile("./package.json", "utf8", function (er, data) { console.log(data) })
這段程序是要從硬盤里讀取package.json文件。當所有數據都讀出來后,就會調用那個回調函數。require("fs")是指加載Node提供的文件模塊,讀取的文件內容將用utf8進行編碼。
HTTP服務器如果你有 PHP 開發經驗,會知道在成功運行 PHP 之前先要配置一個功能強大而復雜的 HTTP 服務器,譬如Apache、IIS 或 Nginx,還需要將 PHP 配置為 HTTP 服務器的模塊,或者使用 FastCGI 協議調用 PHP 解釋器。這種架構是“瀏覽器 - HTTP 服務器 - PHP 解釋器”的組織方式,而Node.js 將“HTTP服務器”這一層抽離,直接面向瀏覽器用戶。如下圖所示:
接下來,讓我們創建一個 HTTP 服務器吧。建立一個名為 app.js 的文件,代碼如下:
var http = require("http") http.createServer(function(req, res) { res.writeHead(200, {"Content-Type": "text/html"}) res.write("Node.js
") res.end("Hello World
") }).listen(3000) console.log("HTTP server is listening at port 3000.")
上面代碼中,創建HTTP服務器調用了http.createServer()函數。它只有一個參數,是個回調函數,服務器每次收到HTTP請求后都會調用這個回調函數。這個請求回調有兩個參數,請求和響應對象,通常簡寫為req和res。服務器每收到一條HTTP請求,都會用新的req和res對象觸發請求回調函數。
res.writeHead()方法設定了響應狀態碼為200和響應頭中的Content-Type為text/html類型。
response.write()方法表示向請求的客戶端發送響應內容。 內容可以是一個Buffer或字符串,表示要發送的內容。
Node不會自動往客戶端寫任何響應。在調用完請求回調函數之后,就要由你負責用res.end()方法結束響應。所以,最終程序用res.end("
Hello World
")結束了一次響應。在終端中運行node app.js 命令,打開瀏覽器訪問 http://127.0.0.1:3000 試試吧。
流Node在處理數據流上也很強大。你可以把數據流看成特殊的數組,只不過數組中的數據分散在空間上,而數據流中的數據是分散在時間上的。通過將數據一塊一塊地傳送,開發人員可以每收到一塊數據就開始處理,而不用等所有數據都到全了再做處理。
下面我們看一個例子:
var fs = require("fs") var stream = fs.createReadStream("./package.json") stream.on("data", function (chunk) { console.log(chunk) }) stream.on("end", function () { console.log("finished") })
只要有新的數據塊準備好,就會激發data事件,當所有數據塊都加載完之后,會激發一個end事件。
程序可以邊讀取邊處理,這要比等著所有數據都緩存到內存中再處理效率高得多。
Node中也有可寫數據流,可以往里寫數據塊。當HTTP服務器上有請求過來時,對其進行響應的res對象就是可寫數據流的一種。
可讀和可寫數據流可以連接起來形成管道,這是一種高效的數據處理方式,只要有數據準備好就可以處理,不用等著讀取完整個資源再把它寫出去。
用我們上面的HTTP服務器,看看如何把一張圖片流到客戶端:
var http = require("http") var fs = require("fs") http.createServer(function (req, res) { res.writeHead(200, {"Content-Type": "image/png"}) fs.createReadStream("./img.png").pipe(res) }).listen(3000) console.log("Server running at http://localhost:3000/")
在這行代碼中,數據從文件中讀進來(fs.createReadStream),然后數據隨著進來就被送到(.pipe)客戶端(res)。在數據流動時,事件輪詢還能處理其他事件。
小結相信讀到這里,大家對Node的優勢和特性已經有了一些了解,并且通過本文的三個編程小例子,對Node的一些用法也有了一些體會,Node跟所有技術一樣,并不是萬能藥。它擅長解決某些問題,并為我們帶來方便。同樣的,在某些方面,卻是它的短板,比如:計算密集型應用。希望你能在用Node開發之前,多一些合理的考慮,多一份編程的快樂。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95900.html
摘要:端輸入數據到端,對就是輸入流,得到的對象就是可讀流對就是輸出端得到的對象是可寫流。在中,這四種流都是的實例,它們都有事件,可讀流具有監聽數據到來的事件等,可寫流則具有監聽數據已傳給低層系統的事件等,和都同時實現了和的事件和接口。 原文地址在我的博客 node中的Buffer和Stream會給剛接觸Node的前端工程師們帶來困惑,原因是前端并沒有類似概念(or 有我們也沒意識到)。然而,...
摘要:前言隨我來去看看為時未晚第一版較淺顯的知識懂得可忽略本文方向安裝起步搭建運行粗略代過對于資源的管理對于輸出的管理舉例介紹本地開發基礎服務熱更新模塊熱替換初步認識初步構建新建一個文件并進入更目錄是命令初始一個文件表示跳過詢問步驟安裝 前言 隨我來,去看看webpack!(為時未晚)============》第一版(較淺顯的知識,懂得可忽略本文) 方向 安裝,起步搭建運行. (粗略代...
摘要:首先,要確認安裝了,并且創建了目錄并執行初始化。想必看見上面的那么多包會一臉懵逼,沒關系,我第一眼看見這些的那刻,和你現在的表情一樣,下面在適當的時候我會逐個解釋的,你只需要相信我上面的包都是跑所必須的,缺一不可。 關于介紹,只說一句:Angular 2是一個強大、全面、龐大的MVVM框架。 安裝 安裝,也算是一個坎,因為你需要安裝一大堆東西,卻不知道每個東西是做什么的,盡管有Angu...
摘要:寫在前面看到了死月佳楠等朋友都寫了關于的年度總結,總覺得自己也應該寫點東西來回首過去的一年,順便展望一下未來的年。在這份榜單上排在的位置,年也希望更上一層樓。年底跟女朋友結束了四年的戀愛長跑,成功領證。 寫在前面 看到了死月、doodlewind、佳楠等朋友都寫了關于 2017 的年度總結,總覺得自己也應該寫點東西來回首過去的一年,順便展望一下未來的 2018 年。 由于之前忙于撰寫《...
閱讀 3606·2021-11-15 11:38
閱讀 2801·2021-11-11 16:55
閱讀 2551·2021-11-08 13:22
閱讀 2628·2021-11-02 14:45
閱讀 1304·2021-09-28 09:35
閱讀 2568·2021-09-10 10:50
閱讀 463·2019-08-30 15:44
閱讀 2775·2019-08-29 17:06