NodeJS相關筆記(四)

1.io就是數據讀寫、數據流動
◆輸入輸出
◆文件操作的讀寫
◆網絡操作中的請求與響應




2.事件驅動模型
◆主線程會去執行node的代碼,把js代碼放入隊列,形成一個事件環
◆主線程會去把隊列中的同步代碼一個一個的取出來執行
◆在同步代碼執行的時候會檢查有沒有異步代碼
◆異步代碼分爲兩種:1.異步非io,如setTimeOut()、setInterval()。2.異步io文件操作
◆如果是異步非io,那麼就會在當前的同步代碼執行完畢之後,再去執行異步非io的代碼
◆如果是異步io,那麼就會去線程池中取一條線程,用來幫助主線程執行異步io操作
◆主線程一直從隊列中取代碼來執行,當隊列中沒有代碼了就會退出
◆線程池中的線程在沒有異步io操作的時候就會休息
◆如果異步io操作有回調函數,那麼子線程就會在執行異步io操作之後再把回調函數中的代碼放回隊列裏,讓主線程再去執行。
◆隊列中每一項,都會有一個狀態記錄,主線程會輪詢隊列中的狀態,異步io操作就靠這個狀態來確定是否執行完畢。



3.項目迭代
◆加新功能
◆減舊功能
◆修改功能
◆用新技術重改一遍舊的項目
◆不停的更新版本:v(1),v(2),v(3),v(4)...


4.遞歸
◆自己調用自己
◆根據條件來停止自己調用自己
◆f(f()),f(f(f())),f(f(f(f()))),f(f(f(f(f()))))...


5.angularjs中的$http
◆then方法,裏面包含兩個函數,分別對應success和error:

$http({
method:'GET',
url:'xxx'
}).then(function(data){
//then的成功方法中返回的data是整個報文,如果要取裏面的json數據,就使用data.data了,
這個和直接.suncess不一樣的,.suncess返回的data就是then的成功方法裏的data.data
},function(error){
//錯誤方法返回的error是一樣的。
})



6.js調試
◆可以使用在js代碼中加debuger,相當於在頁面加斷點,不過這是老的用法了。


7.nodejs調試
◆node內置調試器:命令調試法【
◇啓動調試:node debug hello.js
◇常用命令:
△help:查看可用命令列表
△n(下一步):代碼默認會從第一行開始調試,會跳出方法不去看方法裏面的
△s(步入):進去方法裏面,進去之後就n,如果再s可能就進去nodejs內部代碼了。
△o(步出):進去方法裏面後跳出方法

◆nodejs第三方工具調試:node-inspector【
◇一個第三方調試工具:node-inspector
◇https://github.com/node-inspector/node-inspector
◇安裝:npm install -g node-inspector
◇啓動調試器:node-inspector,保持掛起不要關閉
◇打開另一個命令臺,以調試模式啓動程序:node-debug foo.js
◇打開瀏覽器訪問:http://localhost:8080/debug?port=5858
◇然後沒報錯的話,打開開發人員工具,你就可以像往常調試js代碼一樣,進行調試它,點擊Sources。



◆Visual Studio Code調試:對node調試很親和(推薦使用)【
◇打開新鍵窗口,打開文件夾
◇打開要調試的文件,按f5,選擇nodejs環境,當然你如果只有nodejs環境那就不用選擇,編輯器會生成一個launch.json
◇修改launch.json相關內容,主要是name和program字段,name是你起的調試名稱,program是你選擇的要調試的文件。
◇點擊編輯器左側長得像甲殼蟲的那個按鈕
◇點擊左上角調試後面的按鈕,啓動調試
◇打上斷點,開始調試(只要你會chrome調試,就很容易)
◇vscode它會根據的你的文件來判斷你這需要什麼,如js它就會去全局環境中去找nodejs,找不到那就是你沒有配置好,如果你安裝了nodejs,那麼可能默認就是nodejs了
◇vscode調試資料的網站:http://i5ting.github.io/vsc/(vsc教程)

◆WebStorm調試:【
◇在要調試的腳本中打好斷點之後右鍵選擇Debug(調試運行)即可開啓調試,只要你會chrome調試,點擊下一步、步入、強制步入、步出,也可以通過命令
△F8  Step over
△F7  Step into
△Shift + F7 Smart step into
△Shift + F8  Step out
△Alt + F9  Run to cursor
△Alt + F8  Evaluate expression
△F9  Resume
△Ctrl + F8  Toggle breakpoint
△Ctrl+Shift+F8  View breakpoints

◆重型的開發工具叫IDE(集成開發環境),IDE中一般都有調試工具


8.ECMAScript6
◆因爲標準所以需要兼容再兼容
◆http://www.ecma-international.org/ecma-262/6.0
◆不同版本瀏覽器對ES6的支持情況:kangax.github.io/es5-compat-table/es6/
◆Node.js因爲採用了Chrome V8引擎,所以對於ES6的支持非常好,運行在服務器端,Node開發不用考慮兼容性問題
◆http://es6.ruanyifeng.com/這個是阮一峯寫的ECMAScript6


8.ECMAScript6新語法
◆ECMAScript5中的use strict是一個很重要的東西,表示讓語法更加嚴格,這樣你就不會因爲寫了保留字而導致在未來出現兼容性的問題了。
◆'use strict':
◇消除Javascript語法的一些不合理、不嚴謹之處,減少一些怪異行爲,如你直接寫a=0;,鬼知道這是個什麼鬼
◇消除代碼運行的一些不安全之處,保證代碼運行的安全,如果你使用了保留字(未來的關鍵字),直接給你報錯,如Unexpected strict mode reserved word,這樣的錯誤說明你用了保留字做爲參數名,它的保留字啊,其實都是其它語言裏出現過的關鍵字。
◇爲未來新版本的Javascript做好鋪墊,因爲只有這樣才能讓低版本的js文件裏的代碼兼容性更好

◆let:定義變量,使用let後,一個作用於下,同一變量名只能夠定義一次,這和var裏的變量提升的機制不一樣,並且作用域更加嚴格了,不再是隻能使用function來定義作用域了,使用let後,let定義的變量的作用域就是一個花括號內了。
◆塊兒級作用域:凡是被{}包裹的代碼就屬於一個代碼塊兒,其作用類似於(function(){})()在這裏面的{}。
◆const:定義常量,原來是通過變量名全部大寫來約定爲常量,現在可以使用const直接定義常量,並且你改常量就會報錯,如PI或者你nodejs引入一個包返回的對象賦值給一個常量名。
◆nodejs裏面你完全可以使用let和const來代替var。
◆箭頭函數:()=>{}相當於function(){}



9.字符串擴展
◆includes(s):表示是否找到了指定s參數字符串
◆startsWith(s) :表示參數字符串是否在源字符串的頭部
◆endsWith(s):表示參數字符串是否在源字符串的尾部
◆s.repeat(n):將原字符串s重複n次並返回,這個很不錯。
◆模板字符串``,是用``和${}來代替字符串拼接
◇增強版的字符串:用反引號`作爲標識,以前是用"或者'
◇模板字符串中所有的空格和縮進都會被保留
◇在模板字符串中嵌入變量:${變量名},可以有多個,就是原來使用"hilo"+name+"....";,現在可以這樣`hilo${name}....`;,效果一樣了,非常方便
◇模板字符串可以是原始的:String.raw`hello world\n`,通過String.raw`hello world\n`可以返回字符串"hello world\n",也就是說可以轉換的。



10.異步流程控制的解決方案 
◆超過四個異步嵌套就成了回調地獄火焰山
◆相應的文章:https://cnodejs.org/topic/560dbc826a1ed28204a1e7de
◆promise(一種規範產生的一個對象),其實類似於.then之間傳遞的一個對象,有成功有失敗。
◆代碼原理,將定義一個方法,內部返回一個Promise對象,你將成功要執行的方法和失敗要執行的方法作爲參數傳遞進去,然後Promise對象中定義了一個then方法,這個方法會接受你傳遞進去的兩個參數,並且會根據你這個兩個參數調用之後返回的值來決定是否繼續返回新的Promise對象,就這樣Promise對象就可以在then中流動了,這樣就使用了同步的方式去寫異步的代碼了,很好的控制了異步嵌套的問題,return 表示同步,callback表示異步【
'use strict'
const fs=rquire('fs');
var rf=function(){
//resolve表示成功、reject表示失敗
return new Promise(function(resolve,reject){
fs.readFile('./a.js','utf8',(err,data)=>{
if(err){
//失敗
return reject(err);
}else {
//成功
return resolve(data);
}
})
})
}
rf().then(function(data){
如果你還想繼續往下執行,可以再renturn一個Promise對象回去
console.log(data);
},function(err){})

◆其實真正then方法不需要判斷你的返回值,而是作爲一個代理方法,無論成功失敗是否返回值,then都會自己返回一個Promise對象給你,鏈式變成return this。





11.Buffer
◆十六進制
◆字節的轉化

1漢字=2字節  00100010 00000000
1字節(Byte)=8字位=8個二進制數 
1字位(bit)=1個二進制數 
1B=8b 
1KB=1024B 
1MB=1024KB 
1GB=1024MB 

◆fs.readFile('./1.js',(err,data){
//返回的是一個Buffer,是 十六進制的機器碼轉化後的字節,因爲第二個參數應該傳遞'utf8'
console.log(data);
})
◆創建Buffer
◇Buffer 是一個像 Array 的對象,它的元素爲16進制的兩位數(0-255的值),主要用於操作字節
◇Buffer 是一個全局對象,使用的時候不需要 require了
◇new Buffer(size),創建一個Buffer並設置大小,返回的對象你像操作數組對象一樣就可以了,如buf[0]=254;,輸出的時候顯示這個地方爲FE
◇new Buffer(str,[encoding]),創建一個Buffer並傳遞參數字符串,然後按照指定的編碼進行解析成二進制碼。
◆Buffer的一些屬性和方法
◇buf[index] 通過下標訪問 buffer 的某個字節的數據
◇buf.indexOf(value,[byteOffset],[encoding]) 查找某個字符在 buffer 內存中的字節下標
◇ buf.includes(value,[byteOffset],[encoding])
◇ buf.length
◇ buf.slice([start,[end]])
◇ buf.toString([encoding],[start], [end])
◇ buf.write(string,[offset],[length],[encoding])

◆開源中國 官網網站提供的一個工具頁面:http://tool.oschina.net/
◆解決 Node 原生不支持的一些編碼 通過 第三方包:iconv-lite(https://www.npmjs.com/package/iconv-lite),第三方包可以解決 gbk 等編碼不支持的問題




12.文件流:用來讀大文件
◆fs.readFile()和fs.writeFile()只能夠讀讀小文件,讀大文件,內存就爆炸了。
◆對大文件的處理,例如下載之類的,可以通過文件流的形式傳輸大文件【
'use strict'
const fs=require('fs');
//將要讀文件變成一缸水
    const rs = fs.createReadStream(p1);
//將要寫的文件變成一個缸
    const ws = fs.createWriteStream(p2);
//使用管道通一通 ok
    rs.pipe(ws);

◆控制文件流:監聽stream對象裏面的事件來控制讀寫流【
'use strict'
const fs=require('fs');
//將要讀文件變成一缸水
    const rs = fs.createReadStream(p1);
//將要寫的文件變成一個缸
    const ws = fs.createWriteStream(p2);
//沒讀到一下塊兒就觸發一次事件,chunk就這一下塊兒的buffer
//讀數據的事件
rs.on('data',function(chunk){
console.log('讀了一下',chunk.length);
ws.write(chunk);
});
//寫數據結束的事件
rs.on('end',function(){
console.log('讀完了');
ws.end();
})

◆讀取流的時候或者進度:【
'use strict'
const fs=require('fs');
//將要讀文件變成一缸水
    const rs = fs.createReadStream(p1);
//將要寫的文件變成一個缸
    const ws = fs.createWriteStream(p2);
//取文件相對應的stats對象
    var stats=fs.statSync('p1');
//文件大小
    var count=stats.size;
//傳輸的文件默認傳了0
    var data=0;


//沒讀到一下塊兒就觸發一次事件,chunk就這一下塊兒的buffer
//讀數據的事件
rs.on('data',function(chunk){
//已經讀了多少
data+=chunk.length;
console.log(parseFloat(data/count*100)+'%');
ws.write(chunk);
});
//寫數據結束的事件
rs.on('end',function(){
console.log('結束');
ws.end();
})


















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章