ES2017 的主要功能有什么?

1,684 阅读6分钟

ES2017 的主要功能有什么以及 ES2018 会带来什么?分两部分去探索最新最好的 ECMAScript 的特性。第一部分探索主要特性如异步函数、共享内存以及 atomics ,而第二部分探索其余特性。

看看 ECMA International, Technical Committee 39 ,事实证明 ES6 中的6并不是发布所需的年数。由于 ES6/ES2015 花了很长时间发布(6年),委员会决定每年去发布一点。我认为这种势头会让事情发生变化,并改善 JavaScript 。ES2017 会带来什么, ES2018 的列表呢?

你可以了解 TC39 议程进展从2ality通过Axel Rauschmayer:The TC39 Process for ECMAScript Features

ES2017

一月的 TC39 会议,该小组就 ECMAScript 提案进行了解决,该提案将被视为 ES2017 的功能(也被称为 ES8,这应该是为了避免混淆)。列表包括:

主要特性

次要特性

在该文章中,第一部分介绍上述所列的主要特性。第二篇文章介绍次要特性。

Async Functions

Async Functions on GitHub (Proposed by Brian Terlson)

在 ES2015 ,我们使用 promise 帮助我们避免回调地狱。

async/await 语法受 TJ Holowaychuk 的 Co 软件包启发,读起来像同步代码。总结, async/await 关键字 及 try/catch 块使得函数异步执行。它们像 generateors 一样工作,但没有转换为 Generateor 函数。这是这样的:

// Old Promise Town  
function fetchThePuppies(puppy) {
  return fetch(puppy)  
  .then(puppyInfo => puppyInfo.text())
  .then(text => {
    return JSON.parse(text)
  })  
  .catch(err =>
    console.log(`Error: ${err.message}`)
  )
}

// New Async/Await City  
async function fetchThePuppies(puppy) {
  try {
    let puppyInfo =  await  fetch(puppy)
    let text =  await puppyInfo.text()
    return  JSON.parse(text)
  }
  catch (err) {
    console.log(`Error: ${err.message}`)
  }
}

这并不意味着你应该把所有 promise 代码替换成 async/await 。就像你不会把每一个函数都用箭头函数(希望),只在最合适的地方用这个语法。我不会讲太多细节因为有盖了 async/await 。去看一下。(上面前一个句子给了一些博文)。在即将到来的一年中,我们将看到人们如何使他们的代码更具有可读性和更高效的使用 async/await 。

共享内存及 Atomics

Shared Memory and Atomics on GitHub (Proposed by Lars T. Hansen)

这个 ECMAScript 提案引入了 SharedArrayBuffer 和一个命名空间对象 Atomics 以及辅助函数至 ES2017 。

我们使用 JavaScript 在浏览器中使用更多操作,这些操作依赖于 JIT 即时编译器和快速 CPU 。不幸的是,正如 Lars T. Hansen 在他的一篇很棒的2016年三月的文章A Taste of JavaScript's New Parallel Primitives中说。

JS JIT 现在性能提升缓慢,并且 CPU 性能的改进大多停滞不前。 现在所有的消费级设备(从台式机系统到智能手机)都拥有多个 CPU (真正的 CPU 内核),而不是更快的 CPU ,除了低端以外,它们通常有两个以上。 一位想要为程序提供更高性能的程序员必须开始并行使用多个内核。 这对于所有用多线程编程语言( Java , Swift , C# 和 C ++ )编写的“本机”应用程序来说都不是问题,但是对于多 CPU 上运行非常有限的 JS 是个问题( web workers, 只有缓慢的消息传递和少数方式去避免数据拷贝)。

SharedArrayBuffer

该提案为我们提供多核计算的构建基础,去研究不同方式去实现 JS 高级并行架构。这些构建基础是什么? SharedArrayBuffer 了解一下。MDN有简洁的定义,我贴在这里:

SharedArrayBuffer 对象作为一个通用的、长度固定的raw二进制数据缓存块,跟 ArrayBuffer 对象相似,但是他们可以在共享内存中创建视图。不像 ArrayBuffer , SharedArrayBuffer 不能分离。

我不知道你会不会跟我第一次读到的时候感受一样 “???”。

基本上,我们能够运行并行任务的首要方式之一是使用 web workers 。由于 workers 运行在它自己的全局环境中且无法分享,除非 workers 间进行交流或者跟主线程交流。更好的是, SharedArrayBuffer 对象允许你去分享字节数据在多个 wrokers 和主线程中。再者,与前身 ArrayBuffer 不同, SharedArrayBuffer 可以同时被多方(例如 web workers 或者 web 页面主程序)引用。你可以使用 postMessage 将 SharedArrayBuffer 从其中一方转移到另一方。把它放在一起,使用 SharedArrayBuffer 在多个工作者和主线程之间传输数据,以便可以一次执行多个任务,这些任务在 JavaScript 中是并行的。

SharedArrayBuffer 新消息

重要!注意 SharedArrayBuffer 的暂时搁置。 如果你最近一直关注这个新闻,你可能会了解到处理器芯片安全设计缺陷导致两个漏洞: MeltdownSpectre阅读它,知道浏览器禁用 SharedArrayBuffer ,直到解决此问题。

Atomics

并行的下一站: Atomics ,一个有两个方法的全局变量。首先,介绍一下 Atomics 方法要解决的问题:在各方(如 web workers 或 Web页面的主程序)共享 SharedArrayBuffer 时,各方可以随时读取和写入其内存。那么,你如何保持一致性及访问顺序化,确保各方知道要等待其他方完成他们的数据写入?

Atomics 有 wakeload 方法。各方将会“休眠”在等待队列中,等待其他方完成写入数据,所以 Atomics.wake 是一个让各方“醒来”的方法。当你需要读数据的时候,你用 Atomics.load 去从某个地点装载数据,这个位置需要输入两个参数,TypedArray,一类数组机制去访问raw二进制数据(即 SharedArrayBuffer),和一个下标去寻找在 TypedArray 的位置。除了我们刚才介绍的内容之外,还有更多的内容,但这是它的要点。

目前, Atomics 只有这两种方法。 最后, Hansen (我们这个提案的作者和并行事物的解释者)说,应该有更多的方法,比如 store 和 compareExchange 来真正实现同步。相对而言,我们正处于 JavaScript 并行的开始阶段,这个提议为我们提供了实现这些目标的基石。

虽然这是一个值得思考的问题,但这仍然是一个高度概括。此更新可能在下一年不会被大多数开发人员使用,但会有助于推进 JavaScript 让每个人受益。 所以,感谢你的阅读,并浏览这些奇妙资源去深入了解!

更多内容:

本文翻译自原文 -ECMAScript Goodies I: Check out the ES2017 Major Features。不定期更新技术博文欢迎star。由于本人水平有限,错误之处在所难免,敬请指正!转载请注明出处,保留原文链接以及作者信息。