Node.js 自學之旅(初稿篇)

學習基礎,JQuery 原生JS有必定基礎,有本身必定技術認知(ps:原型鏈依然迷糊中.閉包6不起來!哎!)javascript

固然最好有語言基礎,C#,java,PHP等等..php

最初學習這個東西的緣由很簡單,在園子裏面看到一篇關於node編寫的小爬蟲 的文章,沒想到這個能夠作一些服務本身的東西而不是公司那些服務用戶啊什麼什麼的.總之不牽扯到公司的技術都很感興趣,後來發現angluar.js裏面也有node.js一點身影,好吧,好吧逼我唄..so 學吧!說實話並不想靠掌握這個若是升職加薪如何如何的,我只想作本身喜歡的事兒寫服從於我本身的程序,就是這麼簡單.html

這裏要說明一下文中不少地方都是各出引用過來,對於不少不明白的地方會針對某個對象,方法等做出補充說明,爭取學習不留死角,通常一片學習不多不多的內容卻須要大量的補充來填補知識空白這也許就是最難的地方.前端

Day 01 java

言歸正傳,node.js簡介:node

簡單的說 Node.js 就是運行在服務端的 JavaScript。python

Node.js 是一個基於Chrome JavaScript 運行時創建的一個平臺。linux

Node.js是一個事件驅動I/O服務端JavaScript環境,基於Google的V8引擎,V8引擎執行Javascript的速度很是快,性能很是好。git

模塊化(module),JS的致命傷一直計劃引進聽說ES6中已經引入了模塊化概念了並無實際實現(知識薄淺,書到用時方恨少),經過實現CommonJS中的Modules1.0概念來完善本身的模塊化npm

   2017-01-03 更新

   補充一下:關於nodejs裏面的模塊化知識點(module),nodejs模塊化大體分爲兩類一類是原生模塊(跟JS同樣原生什麼的都是重中之重),另一類是文件模塊

   文件模塊

文件模塊,我首先想到的是相似與C#裏面文件數據交互相關的IO數據流,其實否則nodejs中文件模塊引用了三種文件識別方式:

  1. .js  既然是模塊化 固然本身得有個專門處理文件的模塊了 -- fs模塊(那筆記下來好不容易找到的--)

       FS模塊剛剛被我言中了,採用的是標準的POSIX文件 I/O操做集(不明白的童鞋本身去百度吧,不能再深刻了!),能夠經過nodejs中的require("fs")來喚起該模塊而且該模塊有同步/異步兩種傳輸方式:

         1)兩種方式不一樣點在於 同步傳遞文件時候會出現程序異常,固然能夠trycatch捕獲到,而異步傳遞時候會直接返回null或者undefined

         2)讀取文件時必定要設置文件編碼,默認編碼是'buffer'若是你在下面的例子中文件裏面輸入的是中文就能明顯的看出來了!

         下面介紹兩個例子,這是下面具體實例:

//文件讀取操做
 var fs = require("fs") ;
 fs.readFile("bb.txt","utf8",function (error,data){
     if(error) throw error ;
     console.log(data) ;
 }) ;

//文件寫入操做
var fs = require("fs") ;
 var txt = "你們要好好學習NodeJS啊!!!" ;
 //寫入文件
 fs.writeFile("bb.txt",txt,function (err) {
     if (err) throw err ;
     console.log("File Saved !"); //文件被保存
 }) ;

  2.".node"  Addon這個是C/C++編寫的操做原理未知...經過其中的dlopen方法來進行加載(想更深刻的童鞋請自行百度)

     3.".Json" 這個你們都不會陌生 尤爲作前端的小夥伴們 這個是調取JSON.parse 方式來解析json數據的

   原生模塊

   關於原生模塊,也就是nodejs自帶模塊仍是參考一下官方文檔吧,畢竟那個東西是最最基礎的最最可信的.

   NodeJS模塊查詢策略

   node提供了兩個對象,exports和require兩個對象,其中exports是模塊公開的接口,require是從外部獲取一個模塊接口,即所獲取模塊的exports對象.(這句話有點難以理解稍後有解釋)

   原生模塊在nodejs編譯進了二進制執行文件,加載速度最快,另外就是文件模塊速度確定比不上原生模塊,可是因爲加載機制,已經加載過的原生模塊和文件模塊不會再次被從新加載,如圖:

   這就很明朗了,這麼吊的圖確定不是我畫的呀 大神傳送門-->https://liuzhichao.com/p/1669.html

    剛纔提到有兩個對象exports和require,這個圖很詳細說明了這哥倆之間的關係,我是這樣理解的:

       require對象就像JQuery中的$選擇器,這個你們確定不陌生,固然有區別的,只是個比喻 若是把頁面元素都劃分爲模塊的話$("<div></div>"),很簡單吧.我選擇的就是div這個模塊,比如require("fs")選擇的是原生模塊fs,有一點不知你們感受到沒有,nodejs緩存機制特別到位,優先緩存查找有點像radis緩存同樣一些已經執行過方法不會被再次執行大大縮減了重複調取的性能損耗,可是這裏不得不說起緩存問題,機制當然好畢竟這東西是一把雙刃劍性能上去了,緩存溢出咋辦?有沒有專業的緩存清理機制,目前還不幾道,不過我確定他絕對有.

     其次require接收的參數是啥? 1.原生模塊 2.相對,絕對路徑文件模塊 3.非原生模塊的文件模塊. require的查找線路是當年文件目錄的node_modules開始找,找不到就找父級目錄node_module以此類推直到根目錄下的node_module文件爲止,第二條的時候你們確定注意到絕對路徑!  沒錯性能就在一瞬間了 若是你給文件模塊地址是絕對地址,必然至關快省去反覆遍歷時間並且require的查找機制不是遍歷全局這種機制  so好好利用這一點:

    

  1. 從module path數組中取出第一個目錄做爲查找基準。
  2. 直接從目錄中查找該文件,若是存在,則結束查找。若是不存在,則進行下一條查找。
  3. 嘗試添加.js、.json、.node後綴後查找,若是存在文件,則結束查找。若是不存在,則進行下一條。
  4. 嘗試將require的參數做爲一個包來進行查找,讀取目錄下的package.json文件,取得main參數指定的文件。
  5. 嘗試查找該文件,若是存在,則結束查找。若是不存在,則進行第3條查找。
  6. 若是繼續失敗,則取出module path數組中的下一個目錄做爲基準查找,循環第1至5個步驟。
  7. 若是繼續失敗,循環第1至6個步驟,直到module path中的最後一個值。
  8. 若是仍然失敗,則拋出異常。

      這裏的異常是有區別的下文說起調用類型有同步異步兩種 同步調用確定就是異常了,這個能夠trycatch截取到 另外就是異步調用啦 返回null或者undefined..很簡單的說 

  Exports  or  module.exports

    首先必須理解了上面哪一個圖,天然而然就會產生一個疑問exports幹毛用的?爲毛都返回的是exports,難道就是簡單的對象返回問題?

    帶着問題,這裏有三個例子:建立兩個文件,server.js和test.js

    server.js中代碼

    

var add=function(a,b){
    return a+b;
};

var minus=function(a,b){
	return a-b;
};

  test.js中的代碼

 

var test=require("./server");
console.log(test.add(4,2));

  而後執行test.js文件 神奇的效果出現了!!      異常報錯!

     修改一下server.js代碼

var add=function(a,b){
    return a+b;
};

var minus=function(a,b){
	return a-b;
};

exports.add=add;
exports.minus=minus;

  結果爲 6!  簡單說明一會兒 首先是require選擇執行文件server.js 結合上面哪一個圖,以後nodejs 就去找了..哎~找到了 可是返回的是啥 他自己不認識 而是經過對象返回才認識的! 這個傳遞的快遞小哥就是exports!很明朗了吧!

吶是否是就能夠認爲返回的東西均可以往exports裏面放呢?真的只是他本身返回的嘛?別忘了以前爲啥叫module模塊化!固然module.exports,這裏我就懶一會兒 不舉例給你們啦 固然原文地址不能少:https://liuzhichao.com/p/1669.html

    關於exports和module.exports 我我的是這樣理解的,由於node中沒有類的概念而某些特定狀況下須要返回一個特定"對象"這種情景下module.exports就排上用場了 指定的對象狀況,而exports並不是指定的對象,也就是位置對象類型,這個有點相似C#中的泛型和非泛型...只是說相似,純屬我的理解.

2017-01-06 補完結

 如題谷歌V8引擎,聽起來吊吊的 實際上也是很吊的,前端開發的同窗對於谷歌瀏覽器並不陌生或多或少接觸過或者使用過我就很少介紹啦,主要是多了我也不知道哈哈.可是最顯而易見的效果在於node處理高併發問題上有突出效果!

安裝環境 windows啊,linux啊,os啊,本身去看 網址在這裏:https://nodejs.org/en/download/

安裝過程就很少說了,哦,有一點對於DOS命令不熟的童鞋們仍是老老實實安裝C盤吧 ,或多或少會用到一點點 .教程:http://jingyan.baidu.com/article/656db9189b826ce381249ce8.html

搞完了以後看看系統PATH環境裏面有沒有配置node.js:

檢測PATH環境變量是否配置了Node.js,點擊開始=》運行=》輸入"cmd" => 輸入命令"path",輸出以下結果:

PATH=C:\oraclexe\app\oracle\product\10.2.0\server\bin;C:\Windows\system32; C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\; c:\python32\python;C:\MinGW\bin;C:\Program Files\GTK2-Runtime\lib; C:\Program Files\MySQL\MySQL Server 5.5\bin;C:\Program Files\nodejs\; C:\Users\rg\AppData\Roaming\npm

彷佛就是你所安裝的node.js的地址不過這東西沒有的話node是運行不起來的!找到它 沒有的話就添加上!

固然能夠手動修改一下Path地址右鍵個人電腦-屬性-高級系統設置-環境變量-找到path 關於nodejs那段文字 修改去吧~只要吧你的文件地址搞上面去就好了,別的別輕易動,雖然我也不知道會發生什麼可是我仍是鼓勵喜歡動手的小夥伴修改一下試試看!

搞完了以後基本工做就完成了!固然安裝的不只僅是node.js安裝同時也會默認安裝臺的包管理工具npm! 我的認爲比較強大的包管理工具,有點像git工具同樣能夠直接用命令從服務器更新啊,下模塊啊,上傳本身的包啊等等,反正很好用能夠搞不少事兒理解有限之後我再詳細研究一會兒
輸入npm-v直接顯示當前npm的版本,今兒先到這吧 該吃飯了!

Day02

繼續昨天的學習,(拍桌!,上課了啊,寫博客的時候確定是歐美音樂最配(Outside--Calvin Harris)).關於npm命令其實不算不少不少,起碼比dos命令少很多呢廢話少說npm命令大全and各個命令用處持續更新中..來自園子內另一位大神~:http://www.cnblogs.com/PeunZhang/p/5553574.html

簡單說一下須要用到的命令,npm install <Module name>  添加模塊,一看就知道 npm install 模塊名稱 沒難度無壓力.還有一點須要注意一下啊,當你install的時候 默認是node安裝目錄的,也就是你的本地目錄local,既然有本地目錄固然就會有全局目錄了!沒錯 npm install <Module name>-g 就是安裝在全局環境中,這兩種有啥區別呢?我嘗試了一下本地安裝local須要npm到指定目錄以後運行指定的模塊,兒全局不用,隨便用隨時隨地,固然這些不是空想,是根據配置文件設定滴找到npm

安裝根目錄有個package.json裏面有全部模塊的安裝信息,版本啊.你問npm的問題基本npm都是在這找的,雖然不少模塊我還木有用過不過感受找到了NPM的老窩了!不少很吊的功能官方文檔比誰說的都清楚:https://docs.npmjs.com/

哦對了,除了nodejs自帶的npm管理器(聽說國內比較慢...沒趕腳)還有國內用的比較多淘寶NPM鏡像能夠直接用npm install一個功能和npm及其類似也有不一樣的地方不多:

$ npm install -g cnpm --registry=https://registry.npm.taobao.org


官方文檔:http://npm.taobao.org/。搞完了以後就能夠用cnpm install愉快的安裝模塊啦

工具方面的已經介紹的差很少啦,言歸正傳,貴言轉正 能夠真正開始nodejs的學習之旅樓

    第一個"應用"(Prayer In C(Lilly Wood and The Prick))

若是咱們使用PHP來編寫後端的代碼時,須要Apache 或者 Nginx 的HTTP 服務器,並配上 mod_php5 模塊和php-cgi。

從這個角度看,整個"接收 HTTP 請求並提供 Web 頁面"的需求根本不需 要 PHP 來處理。

不過對 Node.js 來講,概念徹底不同了。使用 Node.js 時,咱們不只僅 在實現一個應用,同時還實現了整個 HTTP 服務器。事實上,咱們的 Web 應用以及對應的 Web 服務器基本上是同樣的。(這麼有深度的話確定不是我寫的..)

   1.先喚醒nodejs,讓他知道我們在召喚他--->required 初始化自毀程序

   2.已經有了足夠強大的力量必需要創建本身的帝國鞏固勢力啦,建立服務器,他的職責在於監管部門,監聽服務端的各類請求.相似Apache,Nginx等http服務器(表示聽都沒聽過!)

   3.既然有監管的功能固然不能光吃飯不幹活,接收請求,響應請求,客戶端發送http請求,服務端響應請求,還有啥..沒別的了

既然三要素已經有了,還等什麼創建如下本身的帝國吧:

搞一個server.js文件 在npm根目錄裏面

//召喚神龍,喚起nodejs
var DG=require("http");
//建立帝國,創建服務器,我學過一點C#記憶中 http請求中彷佛有兩個參數request和response試試看唄
DG.createServer(function(request,response){
//搞事
//搞個頭部信息粗來簡單點的
    response.writeHead(200, { 'Content-Type': 'text/plain' });

    response.end('HelloWorld\n');
    }).listen(8888);

console.log("Server run at 127.0.0.1:8888");

  麻溜試試去吧,我試了一下  直接 node server.js  好的神龍粗線了, 訪問127.0.0.1:8888  ok瀏覽器粗線了!!

看起來蘇護很難搞的樣子,其實也不是很難.原理大概是這個意思喚起nodejs使用require

 

 Day03 元旦假期回來第一波 (NPM包管理工具自我感受不是很詳細,之後繼續補充)

 Nodejs--REPL 交互式解析器

     聽起來很高大上有木有,幹嗎用的?很簡單來一塊兒看看定義-->看大屏幕-->REPL Read Eval Print Loop交互式解析器,相似某些運行環境  windows..linux..unix等等,咱們能夠輸入命令而後環境進行解析以後給咱們答案!就像計算器同樣你按1+1而後按= 屏幕顯示2,這就是交互解析器!很好理解吧.

     在node上運行一下試試唄,我這是windows環境 直接點擊node.exe 輸入1+1 回車直接出結果了..soeasy 來點簡單邏輯怎麼樣來來看圖:

    REPL解析器都幹了些什麼事兒呢?

      >1.讀取 讀取用戶輸入 解析用戶輸入的javascript代碼

      >2.執行 執行輸入的數據結構

      >3.打印 打印執行結果

      >4.循環 循環操做以上步驟 直到用戶ctrl+c主動退出

  做用:  囉嗦半天只想說明一點,REPL能夠用做模塊測試,它能夠很好的被其餘模塊包容在內能夠本身獨立執行,能夠做爲 debugging testing或者只是執行一些操做獲得一些結果.

ctrl + c - 終止當前命令

ctrl + c twice - 終止Node REPL

ctrl + d - 終止Node REPL

Up/Down Keys - 查看命令歷史記錄和修改之前的命令

tab Keys - 當前指令的列表

help - 全部命令的列表

break - 退出多行表達式

clear - 從多行表達退出

save filename - 當前Node REPL會話保存到文件中

load filename - 加載文件的內容在當前Node REPL會話

解析器這沒啥能夠說的 主要是作測試用 ...三個點是系統自動生成表示程序某些語句未完結,nodejs會自動識別當前語句是否完結,_下劃線能夠表明其中的變量 做爲變量去接收各類參數,可是不推薦這麼搞 很不規範的說

 

 

Day04 回調函數(對於有必定JS經驗的人來講很是很是容易理解)

   其實想寫一些關於回調函數的帖子的!可是..此處省略一萬字, 我發現一些更加實用更應該注意到的事情,都知道nodejs是運行在服務端的js可是後端不少的encod啊decod操做是如何實現的關於編碼格式如何實現的?

那麼就根據這個回調函數一併說一下唄,還有我發現我這種單一帖子續寫很讓人反感,好吧我錯了大大們,明天開始從day05開始我會劃分紅類這樣更加清晰展示每個模塊深挖以後的原理!

  如圖,關於回調神馬的我真的不想說太多,把這個梨子上的代碼老老實實敲打一遍,而後本身運行以後比對一會兒!,原理很簡單 我本身總結就是異步處理與同步處理的區別,這也是處理併發的關鍵點之一,我能夠同時請求A B兩個任務並且不須要他們作出迴應我就能夠繼續去作別的事兒等他們有反應了再來告訴我我再去處理,而同步就不同了一就是一二就是二舅,這件事兒沒完事兒別的啥都別想,兩個方式各有各的優點,做用確定不同.好了再來看這個:

 

 若是你在剛纔的input.txt裏面輸入過中文,控制檯確定顯示的是空唄 這是爲毛線?nodejs對中文支持並很差!記住了並很差!因此須要第三方庫的支持,若是你簡單的相信data.toString()能夠實現願望的話那麼久錯啦,由於這不一樣於其餘後端代碼對於這種多字節的node並不支持,並且toString([encoding],[strat],[end])雖然能夠選擇編碼格式可是卻不支持gbk gb2312 等等多字節編碼.so咱們要引用第三方庫來實現它強大的中文怎麼可能不被支持呢?

  iconv-lite 就是這個庫

相關文章
相關標籤/搜索