共計 6148 個字符,預計需要花費 16 分鐘才能閱讀完成。
這篇文章將為大家詳細講解有關 Node.js v14.x LTS 中的新功能有哪些,文章內容質量較高,因此丸趣 TV 小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
Optional Chaining(可選鏈)
如果我們使用 JavaScript 不管是用在前端或者 Node.js 服務端都會出現如下情況,因為我們有時是不確定 user 對象是否存在,又或者 user 對象里面的 address 是否存在,如果不這樣判斷,可能會得到類似于 Cannot read property xxx of undefined 這樣的類似錯誤。
const user = { name: Tom , address: { city: ZhengZhou } } if (user user.address) { console.log(user.address.city) }
現在我們有一種優雅的寫法 可選鏈操作符,不必明確的驗證鏈中的每個引用是否有效,以符號 ?. 表示,在引用為 null 或 undefined 時不會報錯,會發生短路返回 undefined。
user.address?.city user.address?.city?.length // 結合 ?.[] 的方式訪問相當于 user.address[ city] user.address?.[city] // 結合 delete 語句使用,僅在 user.address.city 存在才刪除 delete user.address?.city
Nullish Coalescing(空值合并)
邏輯或操作符 (||) 會在左側為假值時返回右側的操作符,例如我們傳入一個屬性為 enabled:0 我們期望輸出左側的值,則是不行的。
function Component(props) { const enable = props.enabled || true; // true } Component({ enabled: 0 })
現在我們可以使用 ** 空值合并操作符(??)** 來實現,僅當左側為 undefined 或 null 時才返回右側的值。
function Component(props) { const enable = props.enabled ?? true; // 0 } Component({ enabled: 0 })
Intl.DisplayNames
對于國際化應用需要用到的語言、區域、貨幣、腳本的名稱,現在 JavaScript 開發者可以使用 Intl.DisplayNames API 直接訪問這些翻譯,使應用程序更輕松的顯示本地化名稱。
Language(語言)
let longLanguageNames = new Intl.DisplayNames([zh-CN], { type: language }); longLanguageNames.of(en-US // 美國英語 longLanguageNames.of( zh-CN // 中文(中國) longLanguageNames = new Intl.DisplayNames([ en], { type: language }); longLanguageNames.of(en-US // American English longLanguageNames.of( zh-CN // Chinese (China)
Region(區域)
let regionNames = new Intl.DisplayNames([zh-CN], {type: region regionNames.of( US // 美國 regionNames.of( 419 // 拉丁美洲 regionNames = new Intl.DisplayNames([ en], {type: region regionNames.of( US // United States regionNames.of( 419 // Latin America
Currency(貨幣)
let currencyNames = new Intl.DisplayNames([zh-CN], {type: currency currencyNames.of( CNY // 人民幣 currencyNames.of( USD // 美元 currencyNames = new Intl.DisplayNames([ en], {type: currency currencyNames.of( CNY // Chinese Yuan currencyNames.of( USD // US Dollar
Script(腳本)
let scriptNames = new Intl.DisplayNames([zh-CN], {type: script scriptNames.of( Hans // 簡體 scriptNames.of( Latn // 拉丁文 scriptNames = new Intl.DisplayNames([ en], {type: script scriptNames.of( Hans // Simplified scriptNames.of( Latn // Latin
Intl.DateTimeFormat
Intl.DateTimeFormat API 用來處理特定語言環境的日期格式。
const date = new Date(); // Sunday, January 10, 2021 at 9:02:29 PM GMT+8 new Intl.DateTimeFormat( en-US , { dateStyle: full , timeStyle: long}).format(date) // 21/1/10 中國標準時間 下午 9:02:29.315 new Intl.DateTimeFormat(zh-CN , { year: 2-digit , month: numeric , day: numeric , hour: numeric , minute: numeric , second: numeric , fractionalSecondDigits: 3, timeZoneName: long }).format(date)
String.prototype.matchAll
matchAll() 返回一個包含所有匹配正則表達式的結果,返回值為一個不可重用 (不可重用意思為讀取完之后需要再次獲取) 的迭代器。
matchAll() 方法在 Node.js v12.4.0 以上版本已支持,該方法有個限制,如果設置的正則表達式沒有包含全局模式 g,在 Node.js v14.5.0 之后的版本如果沒有提供會拋出一個 TypeError 異常。
// const regexp = RegExp(foo[a-z]* , g // 正確 const regexp = RegExp(foo[a-z]* // 錯誤,沒有加全局模式 const str = table football, foosball, fo const matches = str.matchAll(regexp); // TypeError: String.prototype.matchAll called with a non-global RegExp argument for (const item of matches) { console.log(item); }
AsyncLocalStorage
Node.js Async Hooks 模塊提供了 API 用來追蹤 Node.js 程序中異步資源的聲明周期,在最新的 v14.x LTS 版本中新增加了一個 AsyncLocalStorage 類可以方便實現上下文本地存儲,在異步調用之間共享數據,對于實現日志鏈路追蹤場景很有用。
下面是一個 HTTP 請求的簡單示例,模擬了異步處理,并且在日志輸出時去追蹤存儲的 id。
const http = require(http const { AsyncLocalStorage } = require(async_hooks const asyncLocalStorage = new AsyncLocalStorage(); function logWithId(msg) { const id = asyncLocalStorage.getStore(); console.log(`${id !== undefined ? id : -}:`, msg); } let idSeq = 0; http.createServer((req, res) = { asyncLocalStorage.run(idSeq++, () = { logWithId( start setImmediate(() = { logWithId( processing... setTimeout(() = { logWithId( finish res.end(); }, 2000) }); }); }).listen(8080);
下面是運行結果,我在第一次調用之后直接調用了第二次,可以看到我們存儲的 id 信息與我們的日志一起成功的打印了出來。
image.png
ES Modules 支持
ES Modules 的支持總體上來說是個好事,進一步的規范了 Node.js 與瀏覽器的模塊生態,使之進一步趨同,同時避免了進一步的分裂。
在當前 Node.js v14.x LTS 版本中已移除試驗性支持,現在使用無需使用標志了,它使用 import、export 關鍵字,兩種使用方式:
使用 .mjs 擴展名
// caculator.mjs export function add (a, b) { return a + b; }; // index.mjs import { add } from ./caculator.js console.log(add(4, 2)); // 6
告訴 Node.js 將 JavaScript 代碼視為 ES Modules
默認情況下 Node.js 將 JavaScript 代碼視為 CommonJS 規范,所以我們要在上面使用擴展名為 .mjs 的方式來聲明,除此之外我們還可以在 package.json 文件中 設置 type 字段為 module 或在運行 node 時加上標志 –input-type=module 告訴 Node.js 將 JavaScript 代碼視為 ES Modules。
// package.json { name : esm-project , type : module , ... }
前端的同學可能會對以上使用 ES Modules 的方式很熟悉。
Top-Level Await
頂級 await 支持在異步函數之外使用 await 關鍵字,在 Node.js v14.x LTS 版本中已去掉試驗性支持,現在使用也不再需要設置標志。
import fetch from node-fetch const res = await fetch(url)
也可以像調用函數一樣動態的導入模塊。
const myModule = await import(./my-module.js
對于異步資源,之前我們必須在 async 函數內才可使用 await,這對一些在文件頂部需要實例化的資源可能會不 好操作,現在有了頂級 await 我們可以方便的在文件頂部對這些異步資源做一些初始化操作。
Diagnostic report(診斷報告)
Diagnostic report 是 Node.js v14.x LTS 提供的一個穩定功能,在某些情況下會生成一個 JSON 格式的診斷報告,可用于開發、測試、生產環境。報告會提供有價值的信息,包括:JavaScript 和本機堆棧信息、堆統計信息、平臺信息、資源使用情況等,幫助用戶快速追蹤問題。
report-toolkit 是 IBM 開發的一個款工具,用于簡化報告工具的使用,如下是一個簡單 Demo 它會造成服務的內存泄漏。
const total = []; setInterval(function() { total.push(new Array(20 * 1024 * 1024)); // 大內存占用,不會被釋放 }, 1000)
最終生成的 JSON 報告被 report-toolkit 工具診斷的結果可能是下面這樣的。
image.png
Stream
新版本中包含了對 Stream 的一些更改,旨在提高 Stream API 的一致性,以消除歧義并簡化 Node.js 核心各個部分的行為,例如:
http.OutgoingMessage 與 stream.Writable 類似
net.Socket 的行為與 stream.Duplex 完全相同
一個顯著的變化 autoDestroy 的默認值為 true,使流在結束之后始終調用 _destroy
使用異步迭代器
使用異步迭代器我們可以對 Node.js 中的事件、Stream 亦或者 MongoDB 返回數據遍歷,這是一件很有意思的事情,盡管它不是 Node.js v14.x 中新提出的功能,例如 event.on 是在 Node.js v12.16.0 才支持的,這些目前看到的介紹還不太多,因此我想在這里做下簡單介紹。
在 Events 中使用
Node.js v12.16.0 中新增了 events.on(emitter, eventName) 方法,返回一個迭代 eventName 事件的異步迭代器,例如啟動一個 Node.js 服務可以如下這樣寫,想知道它的原理的可以看筆者下面提到的相關文章介紹。
import { createServer as server } from http import { on } from events const ee = on(server().listen(3000), request for await (const [{ url }, res] of ee) if (url === /hello) res.end(Hello Node.js! else res.end( OK!
在 Stream 中使用
以往我們可以通過 on(data) 以事件監聽的方式讀取數據,通過異步迭代器可以一種更簡單的方式實現。
async function readText(readable) { let data = for await (const chunk of readable) { data += chunk; } return data; }
目前在 JavaScript 中還沒有被默認設定 [Symbol.asyncIterator] 屬性的內建對象,在 Node.js 的一些模塊 Events、Stream 中是可使用的,另外你還可以用它來遍歷 MongoDB 的返回結果。
關于 Node.js v14.x LTS 中的新功能有哪些就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。