共计 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 中的新功能有哪些就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。