iT邦幫忙

2022 iThome 鐵人賽

DAY 2
0

今天是這個系列的開始,我正職開始寫 node 約有半年,在這個領域仍然正在學習。
JS 的生態系非常的活躍,而且充滿了很多好玩的東西,從來不會覺得無聊。

雖然戰語言是一件無聊的事,這種興趣雖然幼稚,但卻很有趣啊~
我最喜歡看的漫畫類型就是類似終末的女武神那種 呂布對戰雷神索爾、或是某某跟某某打起來,到底誰會贏呢??

程式語言上也是如此,我喜歡寫 node,所以也要知道它的優點是什麼,缺點是什麼!又有什麼有趣的玩具存在於 node 的生態系,這樣我才知道 node 在對抗其他語言,到底誰會贏(?

ps. 本系列文並不是從頭教學文,所以想要從頭學 node 的人請轉彎,但對 node、npm、yarn,稍微有點了解,知道基礎JS 的,應該可以讀,並且歡迎和我一起分享心得。

正文開始。


什麼是 Node?

Node.js 是 Javascript 的一個 runtime,而 runtime 便是可以執行 程式語言的一個環境,因此可以理解為只要有了 runtime,Js 便可以在不同的作業系統及平台去執行,而 Node 便是這樣的東西。


單執行緒

As an asynchronous event-driven JavaScript runtime, Node.js is designed to build scalable network applications.
官網提到,Node 是一個非同步且事件驅動的 runtime,這是什麼意思呢?

一般的 web server 多半都是基於多執行序(multi-threaded)的方式執行的,這種方式會在接收每個 web request 時產生對應的 thread,並且相對消耗記憶體資源。在高併發的場景下,CPU 及 memory 並不足以應付,並且會產生較多的上下文切換(Context-switching)的成本。

而 Node 本身便是為了應付這種場景而被創造出來的工具,如上面提到的 Node 是一個非同步且事件驅動 runtime,而幫助他做到這件事的便是(single-threaded)。


非同步(asynchronous)?

什麼是同步呢?
在同步執行的情況下,我們的程式碼中的任何操作,都會有條有序地一一被執行。

const fs = require('fs');
const data = fs.readFileSync('./input.txt', {encoding:'utf8', flag:'r'});
console.log(data, 'Read completed!');

以上述例子來講,我們使用了 fs.readFileSync 這個方法來讀取 input.txt 這個檔案,因為讀取檔案本身是需要時間的(從硬碟讀取檔案對於程式執行來講是個相對十分慢的動作),在這個範例中程式執行到第二行,會因為讀取檔案需要等待,而在這邊造成阻塞(blocking),直到檔案內容讀取完畢後,才會在下一行印出檔案內容 及 'Read completed!'

然而為了讓單執行序的機制順利發揮,Node 的 API 支援許多非同步的語法,讓開發者在尤其耗時的 IO 操作上,可以不造成執行緒阻塞。

以下是 readFile 的非同步版語法,雖然檔案還未讀取完,但 Read not completed! 字樣的印出會先被執行,而 Read completed! 字樣則會在讀取完成後被印出。

var fs = require('fs');
 
fs.readFile('./input.txt', function (err, data) {
    if (err) throw err;
    console.log(data, 'Read completed!');
});
console.log('Read not completed!');

單執行緒的魔法

由於 web service 是典型的 IO bounded 的應用類型,所以正好符合 Node 的場景,在處理 Request 時可以對 port 進行監聽,並以非同步的方式進行處理而不造成阻塞,並且不用因為大量的請求而佔用過多資源,因為基本上這些請求是共用資源的。

然而單執行緒意味著我們無法善用多 CPU 的資源及優勢,這樣顯然是無法滿足我們的!
不過這部分像是 cluster、PM2、forever 等,其實有許多的解法,在後面的文章會做介紹。

下一章,來提提幫助 node 完成非同步的核心機制 Event Loop。


上一篇
[Day 1] 系列目標
下一篇
[Day 3] Node 的核心機制 - Event Loop
系列文
身為 Node.js 開發者,可以知道一下的事9
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言