本文爲您分享「Node.js 入門你須要知道的 10 個問題」這些問題可能也是面試中會被問到的,固然問題不只僅是這 10 道,所以,最近開源了一個新項目 Nodejs-Interview-Questions 專一於 Node.js 面試題的分享,提供了中英文版本,您也能夠在線預覽: interview.nodejs.red/html
Node.js 是一個基於 Chrome V8 引擎的 JavaScript 運行環境。它是一個開源和跨平臺的服務端應用程序。任何人均可以編寫 JavaScript 代碼來開發 Node.js 應用程序。它能夠運行於 Microsoft Windows、Linux、 或 OS 系統。前端
Node.js 不是一個新的語言,也不只僅是一個基於 JavaScript 的框架,它基於 Chrome 的 JavaScript 運行時,所以代碼的編寫和執行與瀏覽器很是類似。node
Node.js 功能ios
如下是 Node.js 的一些重要功能git
Node.js 使用的單線程模型且採用了事件循環架構,使得編寫可擴展性高的服務器變得既容易又安全。一些傳統的服務端語言會建立多線程來處理請求,一般建立線程都是有系統資源開銷的,所以也會有一些限制,而 Node.js 只建立一個線程來處理更多的請求。github
Node.js 的全部 API 都是異步的。這意味着下一個請求來臨時能夠直接處理而不用等待上一次的請求結果先返回。面試
Node.js 從不緩衝任何任何數據,參見What is No-Buffering feature of Node.jssql
咱們許多人可能會對 Node.js 感到困惑。它不是像 Apache 這樣的 Web 服務器。Node.js 提供了一種新方法來執行咱們的代碼。它是 JavaScript 的運行時。Node.js 提供了建立 HTTP 服務器的方法,咱們能夠在這之上託管咱們的應用程序。npm
Source: Introduction To Node.js編程
咱們能夠從 Node.js 官方網站 nodejs.org/en/ 下載安裝軟件。
nvm 安裝
這裏推薦您使用 nvm 工具安裝,方便後期的升級進行 Node.js 版本管理,如下爲安裝步驟:
驗證安裝結果
在 Node.js 安裝成功以後,咱們能夠檢查它是否正常工做。
打開命令終端,輸入如下命令
$ node
複製代碼
以後將出現 Node 提示符,咱們寫入如下命令,運行查看
console.log("hello world!");
複製代碼
按 Enter 鍵
這是有陷阱的,在相似一些 Unix 系統中你不該該嘗試監聽 80 端口,這麼作你須要擁有超級用戶權限,所以,不推薦你這麼作。
儘管如此,若是你必定要讓應用監聽 80 端口,可使用 Nginx 來實現,在應用前方加上一層反向代理。仍是建議你監聽大於 1024 的端口。
錯誤優先回調函數用於同時返回錯誤(error)和數據信息(data),返回值的第一個參數作爲錯誤信息描述,而且驗證它是否出錯(非錯 error 爲 null),其它參數用於返回數據。
fs.readFile(filePath, function(err, data) {
if (err) {
// 錯誤信息處理
return console.log(err)
}
// return the data object
return data;
})
複製代碼
在 Node.js 中建立一個 Http 服務是很簡單的一件事情,咱們能夠經過 HTTP 模塊來完成這些操做。
const http = require('http');
const server = http.createServer((request, response) => {
if (request.url === '/hello') {
response.writeHead(200, {
'Content-Type': 'text/plain',
});
response.end('hello world!');
} else {
response.end('OK!');
}
});
server.listen(3000, '127.0.0.1', () => {
console.log('service is listening at http://127.0.0.1:3000');
});
複製代碼
Node.js 的核心組建是系統 API、V8 引擎和 Libuv。
Libuv 庫
libuv 庫是一個跨平臺的支持事件驅動的 I/O 庫。它是使用 C 和 C++ 語言爲 Node.js 所開發的。可是它也被應用於 Mozilla's 的 Rust、Luvit、Julia、pyuv 等其它的語言。
libuv 庫是 I/O 操做的核心部分,例如讀取文件和 OS 交互。
關於 Libuv 的學習,能夠參考 libuv中文教程
V8 引擎
來自於谷歌:「V8 是谷歌開源的高性能 JavaScript 引擎」,使用 C++ 開發,並在谷歌瀏覽器中使用。V8 中實現的 ECMAScript 中指定 ECMA - 262 ,第 3版運行在 Windows XP 和 Vista、Mac OS X 的 10.5 和 Linux 系統使用 IA - 32 或 ARM/MIPS 處理器。V8 能夠獨立運行,也能夠嵌入到任何 C++ 應用程序。
若是你感興趣想學習更多的 V8 引擎,請訪問 What is V8?
APIs (NodeJS Core Libs)
Node.js APIs 是根據您的請求去調用一些函數執行一些業務操做。默認狀況下 Node.js 的 APIs 都是異步的,可是你想同步使用也是能夠的(同步方式是不推薦的)。
例如,這個 fs 模塊可使用同步方式也可使用異步方式。
var fs = require('fs');
fs.readFile('/files/help.txt', function(err, buf) {
// use fs.readFileSync() for sync operation. console.log(buf.toString());
});
複製代碼
Source: Introduction to NodeJS, A SSJS: Part I - Components Explained
「回調地獄」是指嚴重的回調嵌套,這些回調嵌套使得代碼變得難以閱讀和維護。
如下是回調嵌套的示例:
query("SELECT clientId FROM clients WHERE clientName='picanteverde';", function(id){
query(`SELECT * FROM transactions WHERE clientId=${id}`, function(transactions){
transactions.each((transac) => {
query(`UPDATE transactions SET value = ${transac.value*0.1} WHERE id=${transac.id}`, (error) => {
if(!error){
console.log("success!!");
}else{
console.log("error");
}
});
});
});
});
複製代碼
在某種程度上,修復「回調地獄」的方式是模塊化。回調被分解爲獨立的函數,這些函數能夠經過參數進行傳遞。因此,針對以上代碼的第一個改進以下所示:
const logError = (error) => {
if(!error){
console.log("success!!");
}else{
console.log("error");
}
},
updateTransaction = (t) => {
query(`UPDATE transactions SET value = ${t.value*0.1} WHERE id=${t.id}`, logError);
},
handleTransactions = (transactions) => {
transactions.each(updateTransaction);
},
handleClient = (id) => {
query(`SELECT * FROM transactions WHERE clientId=${id}`, handleTransactions);
};
query("SELECT clientId FROM clients WHERE clientName='picanteverde';",handleClient);
複製代碼
儘管這個代碼相比第一個示例更容易易讀,並且咱們建立的的函數還能夠獲得複用。可是在某些狀況下,咱們想要使程序更健壯可經過 Promise 來解決。
此外,generators 也提供了強大的回調地獄解決方案,使用它能夠解決不一樣回調之間的依賴關係。然而 generators 會更高級一些使用起來會複雜一些。關於 Generators 更多信息能夠閱讀這篇文章 Generators in Node.js
然而,以上的雖然能很好解決回調地獄問題,可是目前有了更好的方案 Async/Await。使用 Async/Await 須要注意 Node.js 版本要在 v7.5 版本之上。
Source: 8 Essential Node.js Interview Questions
事件驅動程序是由事件(click、load 等)決定的代碼流程術語。它是當今流行編程語言(例如 C#、Java)裏一個最基本的里程碑,在這裏不會詳細講述。在 Node.js 中或者一些其它類型的 JavaScript 項目中,咱們都在使用事件驅動編程。也許你並不知道事件驅動編程,可是在一些頁面加載或按鈕單擊事件中,你已經在使用了。
舉一個典型的事件驅動流程的例子,看下它是如何在 Node.js 中完成中:
result = getJSONfromDestination();
binddata(result);
複製代碼
上述操做是一個阻塞 I/O(單線程模式下將會等待這個阻塞 I/O 完成以後纔會進行下一步)
如今讓咱們看看異步方式該如何進行(非阻塞 I/O 進程)
json_finished = function(result){
binddata(result);
}
getJSONfromDestination(jsonfinished);
複製代碼
如上所示,這是一個非阻塞的例子,由於 json_finished 不是你所想向的那樣會直接工做。當您調用 getJSONfromDestination 函數並將 jsonfinished 作爲參數傳遞時,它纔開始工做。
Source: NodeJS Series #6: Event - Driven Programming
NPM 是 Node.js 中的包管理器。容許咱們爲 Node.js 安裝各類模塊,這個包管理器爲咱們提供了安裝、刪除等其它命令來管理模塊。這裏有一點咱們須要注意,咱們必需要有一個 package.json 文件或 node_modules 目錄安裝模塊到本地。
NPM 最好的一點是它會在本地存儲咱們所安裝的依賴項,存在於 package.json 的 dependencies 對象裏。例如,若是一個模塊 X 使用了模塊 A 版本爲 1.0,模塊 Y 使用了模塊 A 版本爲 1.5,那麼模塊 X 或 Y 都將在本地擁有本身對應的模塊 A 的副本。
// 模塊 X
{
"name": "X",
"dependencies": {
"A": "^1.0"
}
}
複製代碼
// 模塊 Y
{
"name": "Y",
"dependencies": {
"A": "^1.5"
}
}
複製代碼
須要 NPM 包
當咱們在開發一些 Node.js 項目時,可能會遇到一些地方須要 NPM,例如連接 Redis、MongoDB 或者發送請求 Request 等,有了這些模塊可使咱們更專一於業務開發,固然有時你會有些特別的需求,這時可能須要本身去封裝一個 NPM 模塊,實現複用。
點擊下面 Source 閱讀更多關於 NPM 的相關內容
Source: How to Create Nodejs Module and Publish Over to Npm
Node.js 能夠作 Web 服務端、命令行工具 (Java, PHP 能夠作的 JS 也能夠作),如今讓咱們看下 Node.js 的 10 個應用場景:
Source: What does node. js do? 10 application scenarios for node. js
本片文章首發於慕課網:www.imooc.com/article/289…