如今,愈來愈多的科技公司和開發者開始使用 Node.js 開發各類應用。Node.js除了可以輔助大前端開發外,還能夠編寫Web應用,封裝Api,組裝RPC服務等,甚至是開發VSCode編輯器同樣的PC客戶端。和其它技術相比, Node.js 簡單易學,性能好、部署容易,可以輕鬆處理高併發場景下的大量服務器請求。Node.js 周邊的生態也很是強大,NPM(Node包管理)上有超過60萬個模塊,日下超過載量3億次。但編寫 Node.js 代碼對新人和其它語言背景的開發者來講,不是一件容易的事,在入門以前須要弄懂很多複雜的概念。前端
a)Node.js簡介vue
早在2007年,Jeff Atwood 就提出了著名的 Atwood定律
java
任何可以用 JavaScript 實現的應用系統,最終都必將用 JavaScript 實現node
固然了,Node.js 也有一些缺點。Node.js 常常被人們吐槽的一點就是:回調太多難於控制(俗稱回調地獄)和 CPU 密集任務處理的不是很好。可是,目前異步流程技術已經取得了很是不錯的進步,從Callback、Promise 到 Async函數,能夠輕鬆的知足全部開發需求。至於 CPU 密集任務處理並不是不可解,方案有不少,好比經過系統底層語言 Rust 來擴展 Node.js,但這樣會比較麻煩。筆者堅信在合適的場景使用合適的東西,尤爲是在微服務架構下,一切都是服務,能夠作到語言無關。若是你們想使 JavaScript 作 CPU 密集任務,推薦 Node.js 的兄弟項目 fibjs,基於纖程(fiber,能夠簡單理解爲更輕量級的線程),效率很是高,兼容npm,同時沒有異步回調煩惱。 b)什麼是Node.js?mysql
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.react
npm
做爲包管理器,目前 npm
是開源庫裏包管理最大的生態,功能強大,截止到2017年12月,模塊數量超過 60 萬+c)基本原理jquery
下面是一張 Node.js 早期的架構圖,來自 Node.js 之父 Ryan Dahl 的演講稿,在今天依然不過期,它簡要的介紹了 Node.js 是基於 Chrome V8引擎構建的,由事件循環(Event Loop)分發 I/O 任務,最終工做線程(Work Thread)將任務丟到線程池(Thread Pool)裏去執行,而事件循環只要等待執行結果就能夠了。 git
![]()
![]()
核心概念程序員
Chrome
瀏覽器中被使用。Chrome V8 引擎能夠獨立運行,也能夠用來嵌入到 C/C++ 應用程序中執行。libuv
提供)libuv
提供)梳理一下es6
libuv
由事件循環和線程池組成,負責全部 I/O 任務的分發與執行1)js語法必須會
2)我的學習和技術選型都要按部就班
能夠看出個人思路,先能寫,而後再追求更好的寫法,好比面向對象。等團隊水平到必定程度了,而且穩定的時候,能夠考慮更加極致的函數式寫法。
3)各類高級的JavaScript友好語言
JavaScript友好語言指的是可以使用其餘語法實現,但最終編譯成js的語言。自從Node.js出現後,這種黑科技層出不窮。好比比較有名的coffee、typescript、babel(es)等。
CoffeeScript雖然也是JavaScript友好語言,但其語法借鑑ruby,崇尚極簡,對於類型和OO機制上仍是偏弱,並且這麼多年也沒發展起來,仍然是比較小衆的活着。將來比例會愈來愈少的。
顯然TypeScript會愈來愈好,TypeScript 的強大之處是要用過才知道的。
當下前端發展速度極快,以指數級的曲線增加。之前可能1年都不必定有一項新技術,如今可能每月都有。大前端,Node全棧,架構演進等等都在快速變化。能夠說,前端越複雜,有越多的不肯定性,TypeScript的機會就越大。 4)再論面向對象
面向對象想用好也不容易的,並且js裏有各類實現,真是讓人眼花繚亂。
《Node.js in action》一書裏說,Node.js 所針對的應用程序有一個專門的簡稱:DIRT。它表示數據密集型實時(data-intensive real-time)程序。由於 Node.js 自身在 I/O 上很是輕量,它善於將數據從一個管道混排或代理到另外一個管道上,這能在處理大量請求時持有不少開放的鏈接,而且只佔用一小部份內存。它的設計目標是保證響應能力,跟瀏覽器同樣。
這話不假,但在今天來看,DIRT 仍是範圍小了。其實 DIRT 本質上說的 I/O 處理的都算,但隨着大前端的發展,Node.js 已經再也不只是 I/O 處理相關,而是更加的「Node」!
nw.js/electron
、移動端 cordova
、HTML五、react-native
、weex
,硬件 ruff.io
等Vue
\ Angular
輔助開發,以及工程化演進過程(使用Gulp
/Webpack 構建 Web 開發工具)npm
上各類工具模塊,包括各類前端預編譯、構建工具 Grunt
/ Gulp
、腳手架,命令行工具,各類奇技淫巧等Node.js 應用場景很是豐富,好比 Node.js 能夠開發操做系統,但通常我都不講的,就算說了也沒多大意義,難道你們真的會用嗎?通常,我習慣將 Node.js 應用場景氛圍7個部分。
1)初衷,server端,不想成了前端開發的基礎設施 2)命令行輔助工具,甚至能夠是運維 3)移動端:cordova,pc端:nw.js和electron 4)組件化,構建,代理 5)架構,先後端分離、api proxy 6)性能優化、反爬蟲與爬蟲 7) 全棧最便捷之路
Node.js是爲異步而生的,它本身把複雜的事兒作了(高併發,低延時),交給用戶的只是有點難用的Callback寫法。也正是坦誠的將異步回調暴露出來,纔有更好的流程控制方面的演進。也正是這些演進,讓Node.js從DIRT(數據敏感實時應用)擴展到更多的應用場景,今天的Node.js已經不僅是能寫後端的JavaScript,已經涵蓋了全部涉及到開發的各個方面,而Node全棧更是熱門種的熱門。
直面問題纔能有更好的解決方式,Node.js的異步是整個學習Node.js過程當中重中之重。
我整理了一張圖,更直觀一些。從09年到如今,8年多的時間裏,整個Node.js社區作了大量嘗試,其中曲折足足夠寫一本書的了。你們先簡單瞭解一下。
結論:Promise是必須會的,那你爲何不順勢而爲呢?
推薦:使用Async函數 + Promise組合,以下圖所示。
結論
下面讓咱們看一下調用函數示例,Node.js 文檔裏最常採用下面這樣的回調方式:
function(err, res) {
// process the error and result
}
複製代碼
這裏的 callback
指的是帶有2個參數的函數:"err"和 "res"。語義上講,非空的「err」至關於程序異常;而空的「err」至關於能夠正常返回結果「res」,無任何異常。 b)EventEmitter
事件模塊是 Node.js 內置的對觀察者模式「發佈/訂閱」(publish/subscribe)的實現,經過EventEmitter
屬性,提供了一個構造函數。該構造函數的實例具備 on
方法,能夠用來監聽指定事件,並觸發回調函數。任意對象均可以發佈指定事件,被 EventEmitter
實例的 on
方法監聽到。
在node 6以後,能夠直接使用require('events')
類
var EventEmitter = require('events')
var util = require('util')
var MyEmitter = function () {
}
util.inherits(MyEmitter, EventEmitter)
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
console.log(a, b, this);
// Prints: a b {}
});
myEmitter.emit('event', 'a', 'b');
複製代碼
和jquery、vue裏的Event是很是相似的。並且前端本身也有EventEmitter。 c)如何更好的查Node.js文檔
API是應用程序接口Application Programming Interface的簡稱。從Node.js異步原理,咱們能夠知道,核心在於 Node.js SDK 中API調用,而後交由EventLoop(Libuv)去執行,因此咱們必定要熟悉Node.js的API操做。
Node.js的API都是異步的,同步的函數是奢求,要查API文檔,在高併發場景下慎用。
筆者推薦使用 Dash 或 Zeal 查看離線文檔,常常查看離線文檔,對Api理解會深刻不少,比IDE輔助要好,能夠有效避免離開IDE就不會寫代碼的窘境。 3)中流砥柱:Promise 回調地獄
Node.js 由於採用了錯誤優先的回調風格寫法,致使sdk裏導出都是回調函數。若是組合調用的話,就會特別痛苦,常常會出現回調裏嵌套回調的問題,你們都很是厭煩這種寫法,稱之爲Callback Hell,即回調地獄。一個經典的例子來自著名的Promise模塊q文檔裏。
step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
// Do something with value4
});
});
});
});
複製代碼
這裏只是作4步,嵌套了4層回調,若是更多步驟呢?不少新手淺嘗輒止,到這兒就望而卻步,粉轉黑。這明顯不夠成熟,最起碼你要看看它的應對解決方案吧! Node.js 約定全部Api都採用錯誤優先的回調方式,這部分場景都是你們直接調用接口,無太多變化。而Promise是對回調地獄的思考,或者說是改良方案。目前使用很是廣泛,能夠說是在async函數普及以前惟一一個通用性規範,甚至 Node.js 社區都在考慮 Promise 化,可見其影響之大。
Promise最先也是在commonjs社區提出來的,當時提出了不少規範。比較接受的是promise/A規範。後來人們在這個基礎上,提出了promise/A+規範,也就是實際上如今的業內推行的規範。ES6 也是採用的這種規範。 Promise意味着[許願|承諾]一個尚未完成的操做,但在將來會完成的。與Promise最主要的交互方法是經過將函數傳入它的then方法從而獲取得Promise最終的值或Promise最終最拒絕(reject)的緣由。要點有三個:
遞歸,每一個異步操做返回的都是promise對象
狀態機:三種狀態轉換,只在promise對象內部能夠控制,外部不能改變狀態
全局異常處理 Async函數要點以下:
Async函數語義上很是好
Async不須要執行器,它自己具有執行能力,不像Generator須要co模塊
Async函數的異常處理採用try/catch和Promise的錯誤處理,很是強大
Await接Promise,Promise自身就足夠應對全部流程了,包括async函數沒有純並行處理機制,也能夠採用Promise裏的all和race來補齊
Await釋放Promise的組合能力,外加co和Promise的then,幾乎沒有不支持的場景
通常,後端開發指的是 Web 應用開發中和視圖渲染無關的部分,主要是和數據庫交互爲主的重業務型邏輯處理。但如今架構升級後,Node.js 承擔了先後端分離重任以後,有了更多玩法。從帶視圖的傳統Web應用和面向Api接口應用,到經過 RPC 調用封裝對數據庫的操做,到提供前端 Api 代理和網關,服務組裝等,統稱爲後端開發,再也不是以往只有和數據庫打交道的部分纔算後端。這樣,就可讓前端工程師對開發過程可控,更好的進行調優和性能優化。 對 Node.js 來講,一直沒有在後端取得其合理的佔有率,緣由是多方面的,暫列幾條。
儘管如此,Node.js 仍是盡人皆知,捲入各類是非風口,也算是在大前端浪潮中大紅大紫。緣由它的定位很是明確,補足以 JavaScript 爲核心的全棧體系中服務器部分。開發也是人,可以同時掌握並精通多門語言的人畢竟很少,並且程序員的美德是「懶」,能使用 JavaScript 一門語言完成全部事兒,爲何要學更多呢? 咱們能夠根據框架的特性進行分類
框架名稱 | 特性 | 點評 |
---|---|---|
Express | 簡單、實用,路由中間件等五臟俱全 | 最著名的Web框架 |
Derby.js && Meteor | 同構 | 先後端都放到一塊兒,模糊了開發便捷,看上去更簡單,實際上上對開發來講要求更高 |
Sails、Total | 面向其餘語言,Ruby、PHP等 | 借鑑業界優秀實現,也是 Node.js 成熟的一個標誌 |
MEAN.js | 面向架構 | 相似於腳手架,又指望同構,結果只是蹭了熱點 |
Hapi和Restfy | 面向Api && 微服務 | 移動互聯網時代Api的做用被放大,故而獨立分類。尤爲是對於微服務開發更是利器 |
ThinkJS | 面向新特性 | 借鑑ThinkPHP,並慢慢走出本身的一條路,對於Async函數等新特性支持,無出其右,新版v3.0是基於Koa v2.0的做爲內核的 |
Koa | 專一於異步流程改進 | 下一代Web框架 |
Egg | 基於Koa,在開發上有極大便利 | 企業級Web開發框架 |
對於框架選型
Tips:我的學習求新,企業架構求穩,無非喜愛與場景而已 Web編程核心
異步流程控制(前面講過了)
基本框架 Koa或Express,新手推薦Express,畢竟資料多,上手更容易。若是有必定經驗,推薦Koa,其實這些都是爲了瞭解Web編程原理,尤爲是中間件機制理解。
數據庫 mongodb或mysql都行,mongoose和Sequelize、bookshelf,TypeOrm等都很是不錯。對於事物,不是Node.js的鍋,是你選的數據庫的問題。另一些偏門,想node連sqlserver等估計還不成熟,我是不會這樣用的。
模板引擎, ejs,jade,nunjucks。理解原理最好。尤爲是extend,include等高級用法,理解佈局,複用的好處。其實先後端思路都是同樣的。
Node 的書幾乎都過期了,我該買哪本?
Node 用途那麼多,我該從哪裏學起?
Node Web 框架那麼多,我該怎麼選?