可能是最全的 Node.js 9 新特性整理
先在最前面為我剛開的博客打個廣告:Sangles Blog
這篇文章原定是去年11月寫的,現在三個月過去了…v9.5都出了,這裡就一併總結一下,看看Node 在最新的版本中有什麼變化。
Node.js 每年進行兩次大的發布,2017年10月,Node.js發布了 9.0 版本,與此同時, Node.js 8.9.0 成為了最新的 LTS 版本。這意味著對 8.9.0 的支持將會維持到2019年底,此後的一個LTS版本將會是 Node.js 10
查看 Node.js 發布歷史
Node.js 9 有什麼新特性?
http/2
Node 8.4 首次支持了http/2
const http2 = require(http2);const server = http2.createServer();server.on(stream, (stream, requestHeaders) => { stream.respond({ :status: 200, content-type: text/plain }); stream.write(hello ); stream.end(world);});server.listen(8000);
但由於仍處於實驗性階段,運行時需要加上—expose-http2
參數
$ node --expose-http2 h2server.js
而在node 9中去除了這一參數,可以直接使用
$ node h2server.js
當然由於現在主流瀏覽器只有在HTTPS時才啟用HTTP2,我們要啟動一個https的伺服器,可以參考如何在本地搭建https伺服器
其他關於http/2的變化還包括:
- 新增對 ALTSVC(HTTP Alternative Services) 的支持
- 新增
maxSessionMemory
,限制單個http2線程允許使用的內存上限,一旦超過這個值,http2請求將被拒絕 - 收集並報告有關
Http2Session
和Http2Stream
實例的基本計時信息。 - 改進了
Http2Stream
和Http2Session
的關閉方式,Http2Stream.prototype.rstStream()
方法被移動至Http2Stream.prototype.close()
中 - 在
Http2Session
上引入了新的屬性來確定會話是否安全
關於http/2:
Node.js HTTP/2 documentation
Introduction to HTTP/2
util
- 新增方法
util.isDeepStrictEqual(value1, value2)
,可進行兩個值的深度比較,返回一個布爾值。此前我們常用assert.deepStrictEqual()
進行比較,後者在兩個值不相等時會拋出異常。
const { isDeepStrictEqual } = require(util); const isEqual = isDeepStrictEqual({ a: 1 }, { a: 1 }); console.log(isEqual); //false const { deepStrictEqual } = require(assert) const isEqual = deepStrictEqual({ a: 1 }, { a: 1 }); // throw new errors.AssertionError
- 新增方法
util.callbackify
,可以將 Promise 轉化為callback形式的函數,適用於解決一些兼容性問題的場景:
const { callbackify } = require(util) async function promiseDemo () { await Promise.resolve() } callbackify(promiseDemo)(function (err) { if (err) { return console.error(err) } console.log(finished without an error) })
- 允許在
debuglog()
中使用通配符,通過NODE_DEBUG=foo*
環境運行
const util = require(util); const debuglog = util.debuglog(foo-bar); debuglog(hi there, its foo-bar [%d], 2333);
HTTP/1
- 當傳入的請求無法成功解析時,http模塊現在將返回400狀態碼。在過去,Node.js只會掛斷socket,導致其他伺服器(如nginx)誤以為Node.js伺服器關閉。
- 在此前的版本中,一旦套接字被分配給請求,
request.setTimeout()
就會調用socket.setTimeout()
。 這使得即使底層的套接字永不連接,也會在請求上發出超時事件。在 Node.js 9 中,socket.setTimeout()
僅在底層套接字成功連接時被調用。 - 新增103狀態碼:103 Early Hints 該狀態碼允許伺服器在主報頭之前先發送部分報頭,以達到預載入文件的目的。
更嚴謹的錯誤碼
Node.js核心代碼庫正在慢慢遷移到一個新的錯誤系統,Node.js 9 中採用了更嚴謹的錯誤碼
在Node.js 9 之前,你可能會這樣處理錯誤:
if (err.message === Console expects a writable stream instance) { //do something with the error}
現在則應該用這種方式進行處理:
if (err.code === ERR_CONSOLE_WRITABLE_STREAM) { //do something with the error}
這可能會導致升級中的各種問題,為了使用戶平滑升級,Node.js官方給出了它們採用的錯誤碼,可以在這裡查看
其他變化
- assert 模塊的方法現在可以拋出任何類型的錯誤(RangeError,SyntaxError等)。在之前版本的Node.js中,這些方法只能拋出斷言錯誤(assertion errors)。
- 在先前版本的Node.js中,如果定時器的延時溢出,不會提供任何溢出發生的指示,而在Node.js 9中,定時器會發出警告。
NODE_OPTIONS
新增了stack-trace-limit
屬性,用於開發環境下設置堆棧上限,使用方式:NODE_OPTIONS=--stack-trace-limit=100
- 支持
console.debug
方法,此方法與console.log
表現一致 cluster.settings
中允許通過cwd
屬性配置目標目錄- 在使用Electron等程序時,我們需要控制什麼時候使用v8 platform,為了使Node正常工作,我們有時需要手動創建NodePlatform。Node.js 9 新增了用於創建/銷毀NodePlatform的公共API
- stream模塊中,新增了
state.ending
屬性判斷stream是否已調用end()
方法 async_wrap
新增了兩個屬性值:TCPSERVERWRAP
和PIPESERVERWRAP
,從而允許我們通過連接種類區分伺服器- 添加了新的非同步鉤子,提供一個API來註冊回調從而跟蹤應用程序中的所有非同步資源,記錄其所觀察到的非同步操作的時間信息
- 在N-API(用於構建本地插件的API) 中,Node.js 9中為需要引用當前事件循環的插件添加了一個函數。從而使插件得以訪問當前的事件循環,要注意的是這個特性目前仍是實驗性的
推薦閱讀: