浅谈Node IO操作
學(xué)習(xí)Node就繞不開異步IO, 異步IO又與事件循環(huán)息息相關(guān), 而關(guān)于這一塊一直沒有仔細(xì)去了解整理過, 剛好最近在做項(xiàng)目的時(shí)候, 有了一些思考就記錄了下來, 希望能盡量將這一塊的知識(shí)整理清楚, 如有錯(cuò)誤, 請(qǐng)指點(diǎn)輕噴~~
同步異步 & 阻塞非阻塞
查閱資料的時(shí)候, 發(fā)現(xiàn)很多人都對(duì)異步和非阻塞的概念有點(diǎn)混淆, 其實(shí)兩者是完全不同的, 同步異步指的是行為即兩者之間的關(guān)系, 而阻塞非阻塞指的是狀態(tài)即某一方。
以前端請(qǐng)求為一個(gè)例子,下面的代碼很多人都應(yīng)該寫過
$.ajax(url).succedd(() => {
......
// to do something
})
同步異步
如果是同步的話, 那么應(yīng)該是客戶端發(fā)起請(qǐng)求后, 一直等到serve處理請(qǐng)求完成后才返回繼續(xù)執(zhí)行后續(xù)的邏輯, 這樣客戶端和服務(wù)端之間就保持了同步的狀態(tài)。
如果是異步的話, 那么應(yīng)該是客戶端發(fā)起請(qǐng)求后, 立即返回, 而請(qǐng)求可能還沒有到達(dá)服務(wù)端或者請(qǐng)求正在處理, 當(dāng)然在異步情況下, 客戶端通常會(huì)注冊(cè)事件來處理請(qǐng)求完成后的情況, 如上面的succeed函數(shù)。
阻塞非阻塞
首先需要明白一個(gè)概念, Js是單線程, 但是瀏覽器并不是, 事實(shí)上你的請(qǐng)求是瀏覽器的另一個(gè)線程在跑。
如果是阻塞的話, 那么該線程就會(huì)一直等到這個(gè)請(qǐng)求完成之后才能被釋放用于其他請(qǐng)求。
如果是非阻塞的話, 那么該線程就可以發(fā)起請(qǐng)求后而不用等請(qǐng)求完成繼續(xù)做其他事情。
IO是什么?
I/O(英語:Input/Output),即輸入/輸出,通常指數(shù)據(jù)在內(nèi)部存儲(chǔ)器和外部存儲(chǔ)器或其他周邊設(shè)備之間的輸入和輸出。
異步IO操作
文件讀取的方式是一次性全部讀取,當(dāng)文件過大的時(shí)候,一次性讀取不僅緩慢,而且影響用戶體驗(yàn),那么怎么實(shí)現(xiàn)分步讀取呢,
這就得使用到異步IO的操作,像水流一樣流出一段取得一段。
具體實(shí)現(xiàn):
我們創(chuàng)建一個(gè)文件讀取流,先上代碼
var fs = require("fs");
var data = ""; //聲明一個(gè)空字符串來存讀取的數(shù)據(jù)
var rs = fs.createReadStream("a.txt");
rs.setEncoding("utf-8");
//監(jiān)聽當(dāng)有數(shù)據(jù)流入的時(shí)候
rs.on("data",function(chunc){
data += chunc; //將讀取的數(shù)據(jù)拼接到data上。
console.log("..."); //讀的過程中,我們打印三個(gè)點(diǎn)。
});
rs.on("end",function(){
console.log("沒有數(shù)據(jù)了")
});
我們將 a.txt中的內(nèi)容增加,以讓讀取時(shí)間變長,
代碼中,創(chuàng)建main3.js寫入上面的代碼,使用 reateReadStream創(chuàng)建讀取流對(duì)象,在對(duì)象上使用on監(jiān)聽“data”讀取數(shù)據(jù)的事件,每讀取一段數(shù)據(jù),就會(huì)觸發(fā)這個(gè)事件,當(dāng)讀取完畢, 就會(huì)觸發(fā)“end”事件。
執(zhí)行main3.js,我們就可以看到下面打印的結(jié)果,從打印的多行"..."中,我們就可以看出,讀取了多次才讀完。
將讀取到的數(shù)據(jù),慢慢的寫入 b.txt中
修改mai3.js中的代碼為如下,增加了下面代碼的 4/10/16行,4行表示建立一個(gè)寫入流(如果寫入的文件不存在,會(huì)自動(dòng)創(chuàng)建一個(gè)文件),10行表示往文件寫入東西,16行表示關(guān)閉寫入流。
var fs = require("fs");
var rs = fs.createReadStream("a.txt");
var ws = fs.createWriteStream("b.txt"); //寫入流
rs.setEncoding("utf-8");
//監(jiān)聽當(dāng)有數(shù)據(jù)流入的時(shí)候
rs.on("data",function(chunc){
console.log("..."); //讀的過程中,我們打印三個(gè)點(diǎn)。
ws.write(chunc,"utf-8"); //向文件寫入東西
});
rs.on("end",function(){
console.log("沒有數(shù)據(jù)了");
ws.end(); //關(guān)閉寫入流
});
這樣我們異步的讀取和寫入文件就實(shí)現(xiàn)了
總結(jié)
之所以經(jīng)常會(huì)混亂是因?yàn)闆]有說清楚討論的是哪一部分, 所以同步異步討論的對(duì)象時(shí)雙方,而阻塞非阻塞討論的市對(duì)象自身。
總結(jié)
以上是生活随笔為你收集整理的浅谈Node IO操作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux 强制卸载硬盘 (Device
- 下一篇: 信息安全主动攻击和被动攻击——就在于对内