Node.js整體感知

官方文檔
中文文檔

Node.js是什么

Node.js? is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js' package ecosystem, npm, is the largest ecosystem of open source libraries in the world.

Node.js 是一個(gè)基于 Chrome V8 引擎的 JavaScript 運(yùn)行環(huán)境。
Node.js 使用了一個(gè)事件驅(qū)動(dòng)、非阻塞式 I/O 的模型,使其輕量又高效。
Node.js 的包管理器 npm,是全球最大的開源庫生態(tài)系統(tǒng)。

以上是中英文兩種方式對Node.js的概括,需要我們明確的是,Node.js既不是一門編程語言,也不是一個(gè)某個(gè)領(lǐng)域的框架,而是一個(gè)javascript的運(yùn)行環(huán)境。

chrome V8引擎

Chrome V8, or simply V8, is an open-source JavaScript engine developed by The Chromium Project for Google Chrome and Chromium web browsers.[5] The project’s creator is Lars Bak.[6] The first version of the V8 engine was released at the same time as the first version of Chrome: September 2, 2008. It has also been used in Couchbase, MongoDB and Node.js that are used server-side.

摘自于wiki,簡而言之,即v8是google開源的javascript引擎,被用來在chrome中解釋javascript。

v8

下載Node.js

從官網(wǎng)可知,當(dāng)前最新版本是9.4.0,長期服務(wù)版本是8.9.4,因?yàn)镹ode.js版本迭代比較快,在開發(fā)中,有時(shí)需要高版本,有時(shí)需要低版本,所以我們不推薦直接下載安裝。我們可以使用Node.js版本管理工具nvm

NVM

nvm

按照文檔進(jìn)行下載,完成之后我們命令行輸入以下命令驗(yàn)證:

nvm --version

有反饋說明安裝成功。

我們通過nvm來查看有哪些node版本可供下載:

nvm ls-remote

        v0.1.14
        v0.1.15
        v0.1.16
        v0.1.17
        v0.1.18
        v0.1.19
        v0.1.20
        v0.1.21
        v0.1.22
        v0.1.23
        v0.1.24
        v0.1.25
        v0.1.26
        v0.1.27
        v0.1.28
        v0.1.29
        v0.1.30
        v0.1.31
        v0.1.32
        v0.1.33
        v0.1.90
        v0.1.91
        v0.1.92
        v0.1.93
        v0.1.94
        v0.1.95
        v0.1.96
        v0.1.97
        v0.1.98
        v0.1.99
       v0.1.100
       v0.1.101
       v0.1.102
       v0.1.103
       v0.1.104
         v0.2.0
         v0.2.1
         v0.2.2
         v0.2.3
         v0.2.4
         v0.2.5
         v0.2.6
         v0.3.0
         v0.3.1
         v0.3.2
         v0.3.3
         v0.3.4
         v0.3.5
         v0.3.6
         v0.3.7
         v0.3.8
         v0.4.0
         v0.4.1
         v0.4.2
         v0.4.3
         v0.4.4
         v0.4.5
         v0.4.6
         v0.4.7
         v0.4.8
         v0.4.9
        v0.4.10
        v0.4.11
        v0.4.12
         v0.5.0
         v0.5.1
         v0.5.2
         v0.5.3
         v0.5.4
         v0.5.5
         v0.5.6
         v0.5.7
         v0.5.8
         v0.5.9
        v0.5.10
         v0.6.0
         v0.6.1
         v0.6.2
         v0.6.3
         v0.6.4
         v0.6.5
         v0.6.6
         v0.6.7
         v0.6.8
         v0.6.9
        v0.6.10
        v0.6.11
        v0.6.12
        v0.6.13
        v0.6.14
        v0.6.15
        v0.6.16
        v0.6.17
        v0.6.18
        v0.6.19
        v0.6.20
        v0.6.21
         v0.7.0
         v0.7.1
         v0.7.2
         v0.7.3
         v0.7.4
         v0.7.5
         v0.7.6
         v0.7.7
         v0.7.8
         v0.7.9
        v0.7.10
        v0.7.11
        v0.7.12
         v0.8.0
         v0.8.1
         v0.8.2
         v0.8.3
         v0.8.4
         v0.8.5
         v0.8.6
         v0.8.7
         v0.8.8
         v0.8.9
        v0.8.10
        v0.8.11
        v0.8.12
        v0.8.13
        v0.8.14
        v0.8.15
        v0.8.16
        v0.8.17
        v0.8.18
        v0.8.19
        v0.8.20
        v0.8.21
        v0.8.22
        v0.8.23
        v0.8.24
        v0.8.25
        v0.8.26
        v0.8.27
        v0.8.28
         v0.9.0
         v0.9.1
         v0.9.2
         v0.9.3
         v0.9.4
         v0.9.5
         v0.9.6
         v0.9.7
         v0.9.8
         v0.9.9
        v0.9.10
        v0.9.11
        v0.9.12
        v0.10.0
        v0.10.1
        v0.10.2
        v0.10.3
        v0.10.4
        v0.10.5
        v0.10.6
        v0.10.7
        v0.10.8
        v0.10.9
       v0.10.10
       v0.10.11
       v0.10.12
       v0.10.13
       v0.10.14
       v0.10.15
       v0.10.16
       v0.10.17
       v0.10.18
       v0.10.19
       v0.10.20
       v0.10.21
       v0.10.22
       v0.10.23
       v0.10.24
       v0.10.25
       v0.10.26
       v0.10.27
       v0.10.28
       v0.10.29
       v0.10.30
       v0.10.31
       v0.10.32
       v0.10.33
       v0.10.34
       v0.10.35
       v0.10.36
       v0.10.37
       v0.10.38
       v0.10.39
       v0.10.40
       v0.10.41
       v0.10.42
       v0.10.43
       v0.10.44
       v0.10.45
       v0.10.46
       v0.10.47
       v0.10.48
        v0.11.0
        v0.11.1
        v0.11.2
        v0.11.3
        v0.11.4
        v0.11.5
        v0.11.6
        v0.11.7
        v0.11.8
        v0.11.9
       v0.11.10
       v0.11.11
       v0.11.12
       v0.11.13
       v0.11.14
       v0.11.15
       v0.11.16
        v0.12.0
        v0.12.1
        v0.12.2
        v0.12.3
        v0.12.4
        v0.12.5
        v0.12.6
        v0.12.7
        v0.12.8
        v0.12.9
       v0.12.10
       v0.12.11
       v0.12.12
       v0.12.13
       v0.12.14
       v0.12.15
       v0.12.16
       v0.12.17
       v0.12.18
    iojs-v1.0.0
    iojs-v1.0.1
    iojs-v1.0.2
    iojs-v1.0.3
    iojs-v1.0.4
    iojs-v1.1.0
    iojs-v1.2.0
    iojs-v1.3.0
    iojs-v1.4.1
    iojs-v1.4.2
    iojs-v1.4.3
    iojs-v1.5.0
    iojs-v1.5.1
    iojs-v1.6.0
    iojs-v1.6.1
    iojs-v1.6.2
    iojs-v1.6.3
    iojs-v1.6.4
    iojs-v1.7.1
    iojs-v1.8.1
    iojs-v1.8.2
    iojs-v1.8.3
    iojs-v1.8.4
    iojs-v2.0.0
    iojs-v2.0.1
    iojs-v2.0.2
    iojs-v2.1.0
    iojs-v2.2.0
    iojs-v2.2.1
    iojs-v2.3.0
    iojs-v2.3.1
    iojs-v2.3.2
    iojs-v2.3.3
    iojs-v2.3.4
    iojs-v2.4.0
    iojs-v2.5.0
    iojs-v3.0.0
    iojs-v3.1.0
    iojs-v3.2.0
    iojs-v3.3.0
    iojs-v3.3.1
         v4.0.0
         v4.1.0
         v4.1.1
         v4.1.2
         v4.2.0   (LTS: Argon)
         v4.2.1   (LTS: Argon)
         v4.2.2   (LTS: Argon)
         v4.2.3   (LTS: Argon)
         v4.2.4   (LTS: Argon)
         v4.2.5   (LTS: Argon)
         v4.2.6   (LTS: Argon)
         v4.3.0   (LTS: Argon)
         v4.3.1   (LTS: Argon)
         v4.3.2   (LTS: Argon)
         v4.4.0   (LTS: Argon)
         v4.4.1   (LTS: Argon)
         v4.4.2   (LTS: Argon)
         v4.4.3   (LTS: Argon)
         v4.4.4   (LTS: Argon)
         v4.4.5   (LTS: Argon)
         v4.4.6   (LTS: Argon)
         v4.4.7   (LTS: Argon)
         v4.5.0   (LTS: Argon)
         v4.6.0   (LTS: Argon)
         v4.6.1   (LTS: Argon)
         v4.6.2   (LTS: Argon)
         v4.7.0   (LTS: Argon)
         v4.7.1   (LTS: Argon)
         v4.7.2   (LTS: Argon)
         v4.7.3   (LTS: Argon)
         v4.8.0   (LTS: Argon)
         v4.8.1   (LTS: Argon)
         v4.8.2   (LTS: Argon)
         v4.8.3   (LTS: Argon)
         v4.8.4   (LTS: Argon)
         v4.8.5   (LTS: Argon)
         v4.8.6   (LTS: Argon)
         v4.8.7   (Latest LTS: Argon)
         v5.0.0
         v5.1.0
         v5.1.1
         v5.2.0
         v5.3.0
         v5.4.0
         v5.4.1
         v5.5.0
         v5.6.0
         v5.7.0
         v5.7.1
         v5.8.0
         v5.9.0
         v5.9.1
        v5.10.0
        v5.10.1
        v5.11.0
        v5.11.1
        v5.12.0
         v6.0.0
         v6.1.0
         v6.2.0
         v6.2.1
         v6.2.2
         v6.3.0
         v6.3.1
         v6.4.0
         v6.5.0
         v6.6.0
         v6.7.0
         v6.8.0
         v6.8.1
         v6.9.0   (LTS: Boron)
         v6.9.1   (LTS: Boron)
         v6.9.2   (LTS: Boron)
         v6.9.3   (LTS: Boron)
         v6.9.4   (LTS: Boron)
         v6.9.5   (LTS: Boron)
        v6.10.0   (LTS: Boron)
        v6.10.1   (LTS: Boron)
        v6.10.2   (LTS: Boron)
        v6.10.3   (LTS: Boron)
        v6.11.0   (LTS: Boron)
        v6.11.1   (LTS: Boron)
        v6.11.2   (LTS: Boron)
        v6.11.3   (LTS: Boron)
        v6.11.4   (LTS: Boron)
        v6.11.5   (LTS: Boron)
        v6.12.0   (LTS: Boron)
        v6.12.1   (LTS: Boron)
        v6.12.2   (LTS: Boron)
        v6.12.3   (Latest LTS: Boron)
         v7.0.0
         v7.1.0
         v7.2.0
         v7.2.1
         v7.3.0
         v7.4.0
         v7.5.0
         v7.6.0
         v7.7.0
         v7.7.1
         v7.7.2
         v7.7.3
         v7.7.4
         v7.8.0
         v7.9.0
        v7.10.0
        v7.10.1
         v8.0.0
         v8.1.0
         v8.1.1
         v8.1.2
         v8.1.3
         v8.1.4
         v8.2.0
         v8.2.1
         v8.3.0
         v8.4.0
         v8.5.0
         v8.6.0
         v8.7.0
         v8.8.0
         v8.8.1
         v8.9.0   (LTS: Carbon)
         v8.9.1   (LTS: Carbon)
         v8.9.2   (LTS: Carbon)
         v8.9.3   (LTS: Carbon)
         v8.9.4   (Latest LTS: Carbon)
         v9.0.0
         v9.1.0
         v9.2.0
         v9.2.1
         v9.3.0
->       v9.4.0

通過這條命令,驗(yàn)證我們之前的想法,node的版本非常零碎。我們觀察可以看到,有一些版本的名稱叫iojs。這是因?yàn)閚ode團(tuán)隊(duì)曾經(jīng)有一段時(shí)間分成了兩個(gè)團(tuán)隊(duì)。

我們下載v8.9.4并使用
nvm install 8.9.4
nvm use 8.9.4
node --version
v8.9.4

通過以上命令,我們成功下載并安裝了8.9.4版本。

入門

交互式環(huán)境

我們進(jìn)入命令行,輸入以下命令:

node
// 此時(shí)進(jìn)入了交互式環(huán)境
1+1
2
var s = 'hello world'
console.log(s)
hello world

可以看到,我們輸入node命令之后,就好像進(jìn)入了瀏覽器的console控制臺一樣。

node運(yùn)行js文件

創(chuàng)建js文件并編寫代碼:

mkdir node-demo
cd node-demo
touch index.js
vi index.js  //寫入console.log('hello world')
node index.js
hello world

我們在index.js中編寫了一條最簡單的語句。然后使用node命令來運(yùn)行這個(gè)文件,命令行正常進(jìn)行了打印。

網(wǎng)絡(luò)應(yīng)用程序

As an asynchronous event driven JavaScript runtime, Node is designed to build scalable network applications. In the following "hello world" example, many connections can be handled concurrently. Upon each connection the callback is fired, but if there is no work to be done, Node will sleep.

const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

在官網(wǎng)的About Node.js部分中,有以上一段文字和程序。它告訴我們,Node.js是一個(gè)基于事件驅(qū)動(dòng)的異步j(luò)avascript運(yùn)行環(huán)境,它被設(shè)計(jì)用來構(gòu)建可伸縮的網(wǎng)絡(luò)應(yīng)用程序。
我們訪問localhost:3000,可以正常顯示hello world。

Node.js重要概念

通過上面的學(xué)習(xí),我們已經(jīng)積累了兩個(gè)概念:

  • 異步
  • 事件驅(qū)動(dòng)

事實(shí)上,如果我們隊(duì)Node.js還有了解的話,我們之后Node.js還有一個(gè)特性:

  • 單線程

以上三個(gè)概念或者說特性,是我們了解Node.js的基本路線,也是我們在生產(chǎn)環(huán)境中使用Node.js的理論來源。

異步

異步的另一個(gè)表達(dá)方式叫非阻塞。最直觀的理解就是,我們在讀取一個(gè)超大文件時(shí),cpu不會(huì)死等硬盤去讀取數(shù)據(jù),而是繼續(xù)執(zhí)行后面的代碼,等文件讀取結(jié)束之后,以回調(diào)的形式告知程序。

我們以fs為例,fs是Node.js操作文件的函數(shù)庫:

fs.readFile('/hello.txt', (err, data) => {
  if (err) throw err;
  console.log(data);
});

我們可以看到,讀取文件是一個(gè)異步的操作,文件的內(nèi)容由回調(diào)返回。這樣的特性,在許多編程語言中是沒有的。

我們通過實(shí)際代碼來測試:

async.js

var fs = require('fs');
fs.readFile('./1.txt',function(err,data){
    console.log(data.toString());
});
console.log('hello async.js');

1.txt

hello 1.txt

我們輸入命令:

node async.js
hello async.js
hello 1.txt

我們可以看到,結(jié)果不言而喻。

單線程

我們知道,java語言開發(fā)web應(yīng)用時(shí),就是采用的多線程的模型,每當(dāng)一個(gè)用戶訪問進(jìn)來時(shí),都會(huì)創(chuàng)建一個(gè)線程來處理。這樣的一大弊端就是,頻繁的創(chuàng)建和銷毀線程,對cpu帶來和很大的負(fù)擔(dān),造成了cpu資源的浪費(fèi)。然而,Node.js就走了一條與java完全不同的策略,在Node.js中使用的是單線程的模型。

我們來驗(yàn)證Node.js是否真的是單線程:
修改之前的app.js

const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  console.log('====================='); 
  //s沒有定義
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
  console.log(s);
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

通過以上代碼實(shí)驗(yàn),我們可以這樣認(rèn)識,第一個(gè)用戶成功訪問后,服務(wù)器出現(xiàn)了異常,第二個(gè)用戶再訪問時(shí),服務(wù)已經(jīng)斷開,無法應(yīng)答。所以說,用Node寫后端對我們的代碼質(zhì)量要求非常高,一個(gè)錯(cuò)誤就能搞垮程序,其它人就無法訪問了。單線程的好處就是,減小了創(chuàng)建和銷毀線程的開銷,在低端機(jī)器上也能發(fā)揮最大的性能。

事件驅(qū)動(dòng)

可以說,Node之所以能在單線程環(huán)境中,實(shí)現(xiàn)異步IO,根本原來就是,Node實(shí)現(xiàn)的事件驅(qū)動(dòng)算法機(jī)制。

我們知道,java能實(shí)現(xiàn)異步編程,是因?yàn)橛卸嗑€程的存在,那么Node靠單線程是怎么實(shí)現(xiàn)異步IO的,是一個(gè)值得探討的問題。

我們思考一個(gè)場景,比如說,現(xiàn)在有一家黃燜雞米飯小店,服務(wù)員只有一個(gè)人她需要兼顧迎接客人,詢問客人吃什么,從后廚上菜品,擦桌子一系列事情。這樣就導(dǎo)致,她要把所有的事情都做好,就不能在一位客人那里等著客人照著菜單選。她會(huì)告訴客人,選好菜直接叫她,她會(huì)利用客人選菜的時(shí)間,去把剛才另外的客人吃完的桌子擦干凈。這就是事件驅(qū)動(dòng)。什么時(shí)間點(diǎn)應(yīng)該去做哪件事情就是異步事件算法應(yīng)該實(shí)現(xiàn)的策略。

所以,Node就跟這位服務(wù)員一樣,累死累活的干活,效率還是非常高的。

npm (Node Package Manager)

npm是node包管理器,類似于java中maven,gradle。
npm

npm之上有非常豐富的第三方j(luò)avascript函數(shù)庫,減少了我們重復(fù)找輪子的過程。比如:
lodash
axios

npm的使用

在node安裝成功之后,npm即會(huì)隨之安裝,我們驗(yàn)證npm是否安裝成功:

npm --vserion
5.6.0

出現(xiàn)數(shù)字,說明本地已經(jīng)有了npm工具。

我們用npm創(chuàng)建項(xiàng)目:

rm -rf node-demo
mkdir node-demo
npm init

一路回車,npm會(huì)在根目錄下生成一個(gè)名為package.json的文件,它記錄這個(gè)項(xiàng)目的相關(guān)信息。
在講解命令用法之前,先梳理一下npm相關(guān)命令:

  • npm init 根據(jù)選擇項(xiàng),為項(xiàng)目創(chuàng)建package.json文件
  • npm install 根據(jù)package.json中的dependencies和devdependencies下載依賴包
  • npm install package-name 下載指定的包,并添加到dependencies中
  • npm install package-name --save 下載指定的包,并添加到dependencies中
  • npm install package-name --save-dev 下載指定的包,并添加到devdependencies中
  • npm install package-name -g 安裝到全局 一般在安裝cli工具時(shí)使用 -g
cat package.json
{
  "name": "demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

有版本,描述,協(xié)議等內(nèi)容。

我們安裝lodash

npm install lodash --save

成功之后,我們觀察到文件中有了一些變化,package.json中。多了一行內(nèi)容:

"dependencies": {
    "lodash": "^4.17.4"
  }

--save命令不僅將包安裝,并將包的名稱加入到dependencies中。

根目錄中多了一個(gè)node_modules文件夾,里面存放著我們下載的lodash。

我們所有通過npm install安裝的包都會(huì)放置在node_modules文件夾中。

此時(shí),我們就可以使用lodash:

var _ = require('lodash')

_.forEach([1, 2], function(value) {
  console.log(value);
});
1
2

node中,使用require引入模塊。

cnpm

cnpm是淘寶開源的一個(gè)代替npm工具,使用的淘寶鏡像,速度非??臁?br> cnpm
安裝:

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

之后,任何使用npm的地方我們都可以使用cnpm

yarn

yarn也是一個(gè)npm客戶端,與npm相比,速度更快更安全,推薦用yarn來代替npm。
yarn

Node.js模塊化

我們之前用到require函數(shù),知道了可以引入模塊,與之對應(yīng)的還有向外暴露模塊,向外暴露有兩種方式:

  • exports
  • module.exports

創(chuàng)建util.js

function pingfang(x) {
    return x * x ;
}

exports.pingfang = pingfang

修改index.js

var util = require('./util.js')
console.log(util.pingfang(3))

可以正常得出結(jié)果為9.

創(chuàng)建user.js

function User(name,age) {
    this.name = age;
    this.age = age;
}

User.prototype.say = function() {
    console.log('my name is '+ this.name);
}

module.exports = User

修改index.js

var User = require('./user.js')
var user = new User('xiaoming',12);
user.say();

可以正常輸出。

至此,我們就介紹完了Node.js中最重要的內(nèi)容。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文由我首發(fā)于 GitChat 中。 前言 在 Node.js 開發(fā)領(lǐng)域中,原生 C++ 模塊的開發(fā)一直是一個(gè)被人...
    機(jī)巧死月不會(huì)碼代碼閱讀 5,397評論 6 24
  • Node.js是目前非?;馃岬募夹g(shù),但是它的誕生經(jīng)歷卻很奇特。 眾所周知,在Netscape設(shè)計(jì)出JavaScri...
    Myselfyan閱讀 4,203評論 2 58
  • 排水溝里的那一抹橘黃 周一清晨,愉快的出門下樓,準(zhǔn)備上班,一周的工作非常飽和,需要加班加點(diǎn)的去完成。走到車前...
    鄉(xiāng)土日照閱讀 428評論 1 1
  • 了解一切,理解所有,所以堅(jiān)持生活下去。 對于活著的人來說,除了活著,只能選擇過的好一點(diǎn),或者將就著過。 一天...
    方亦圓閱讀 177評論 0 0
  • 今天和家里大吵了一架,源頭是因?yàn)槲议|蜜和我媽說,結(jié)婚時(shí)我媽對我說要一心一意的過日子。她就直接說她沒和我說,說我向別...
    一心人的錦繡夢閱讀 182評論 0 0

友情鏈接更多精彩內(nèi)容