ES2017 最佳特性 -- 数组中的异步函数以及共享缓冲区

简介: ES2017 最佳特性 -- 数组中的异步函数以及共享缓冲区

ES2017 最佳特性 -- 数组中的异步函数以及共享缓冲区


自 2015 年起,JavaScript 可谓突飞猛进。

现在使用它比过去要舒服多了。

在本文中,我们将着眼于 ES2017 的最佳特性。

异步函数(Async Functions)和 Array.prototype.forEach()

Array.prototype.forEach 并不适用 asyncawait 语法。

举例来说,如果有如下代码:


async function downloadContent(urls) {
  urls.forEach(async url => {
    const content = await makeRequest(url);
    console.log(content);
  });
}

那么并不会得到包含若干 promise 的结果,因为 forEach 不会等待每个 promise 完成。

取而代之的是,可以用 for-of 循环来迭代每个异步函数以获取结果:


async function downloadContent(urls) {
  for (const url of urls) {
    const content = await makeRequest(url);
    console.log(content);
  }
}

for-of 循环能感知 await 操作符,所以可以用它循序运行所有异步函数。

若要并行运行若干异步函数,可以使用 Promise.all


async function downloadContent(urls) {
  await Promise.all(urls.map(
    async url => {
      const content = await makeRequest(url);
      console.log(content);
    }));
}

我们将多个 URL 映射为异步函数的集合,这样一来就能在 promise 数组上调用 Promise.all 了。

调用该方法后会返回一个 promise,其解决值(resolved value)是一个包含了每一个 promise 解决值的数组。

立即调用异步函数表达式

我们也可以创建立即运行的异步函数。

举例来说,相比于以下写法:



async function foo() {
  console.log(await promiseFunc());
}
foo();

我们可以这么写:


(async function () {
  console.log(await promiseFunc());
})();

也可以写成箭头函数:


(async () => {
  console.log(await promiseFunc());
})();

未处理过的 rejection

在使用异步函数时,并不用担心未处理过的 rejection 。

这是因为当浏览器遇到它们时会自动报告。

举例来说,我们可以这样写:


async function foo() {
  throw new Error('error');
}
foo();

而后我们将在控制台中看到被记录的报错信息。

Shared Array Buffers

ES2017 引入的共享数组缓冲区(shared array buffers)使得我们可以构建并发的应用了。

这让我们可以在多个 worker 和主线程之间共享 SharedArrayBuffer 对象的字节数据。

被共享的缓冲由一个类型化数组(typed array)包裹,这样就能访问到它们了。

我们可以快速在 worker 间共享数据,而跨 worker 的数据协同也变得简便了。

举例来说,可以编写如下代码来创建一个共享数组缓冲区:


const worker = new Worker('worker.js');
const sharedBuffer = new SharedArrayBuffer(
  100 * Int32Array.BYTES_PER_ELEMENT);
  
worker.postMessage({
  sharedBuffer
});
const sharedArray = new Int32Array(sharedBuffer);

我们在 worker.js  中创建了一个 worker。

之后我们用 SharedArrayBuffer 创建了一个 shared buffer。

它包含 100 个元素。

接着,为了与其它 worker 共享缓冲区,我们调用了 postMessage 以发送缓冲数据。

要访问缓冲区中的数据,就得创建一个新的 Int32Array 实例。

接下来在 worker.js worker 中,这样编写以获得缓冲数据:


self.addEventListener('message', (event) => {
  const {
    sharedBuffer
  } = event.data;
  const sharedArray = new Int32Array(sharedBuffer);
  //...
});

我们监听了 message 事件并从 event.data 中取得了 sharedBuffer 属性。

之后就能用与先前相同的方式访问它了。

总结

异步函数并不适配既有的数组实例方法。

同时,我们可以使用共享数组缓冲区在主线程和 worker 线程之间共享数据。



相关文章
【C++11特性篇】利用 { } 初始化(1)
【C++11特性篇】利用 { } 初始化(1)
|
6月前
|
Java
动态移除异步
动态移除异步
37 2
|
1月前
|
索引 Python
列表作为序列型对象都支持哪些操作,它们在底层是怎么实现的?
列表作为序列型对象都支持哪些操作,它们在底层是怎么实现的?
43 4
|
存储 缓存 小程序
小程序全局共享数据--存储
小程序全局共享数据--存储
89 0
|
安全
RxSwift特征序列Driver的使用,以及共享附加作用与非共享附加作用的区别?
RxSwift特征序列Driver的使用,以及共享附加作用与非共享附加作用的区别?
170 0
|
Swift 编译器
Swift - 实例对象调用协议方法优先级分析/ witness_methos witness_table分析
本文主要探究: 当一个类遵循了协议,且协议和类都有方法实现时,实例对象调用方法的优先顺序
Swift - 实例对象调用协议方法优先级分析/ witness_methos witness_table分析
|
分布式计算 Hadoop API
FilelnputFormat 切片机制和配置参数| 学习笔记
快速学习 FilelnputFormat 切片机制和配置参数
111 0
|
缓存 Java vr&ar
【Java 网络编程】NIO Buffer 简介 ( 概念 | 数据传输 | 标记 | 位置 | 限制 | 容量 | 标记 | 重置 | 清除 | 翻转 | 重绕 | 链式操作 )
【Java 网络编程】NIO Buffer 简介 ( 概念 | 数据传输 | 标记 | 位置 | 限制 | 容量 | 标记 | 重置 | 清除 | 翻转 | 重绕 | 链式操作 )
196 0
mode:类型非常多 r:只读 从头部开始读 io.UnsupportedOperation: not writable w:写入 每次都是从头部开始写 原有的内容
mode:类型非常多 r:只读 从头部开始读 io.UnsupportedOperation: not writable w:写入 每次都是从头部开始写 原有的内容
|
存储 Java 程序员
在线程异步的场合下,如何将线程信息传递到调用处(1)
在线程异步的场合下,如何将线程信息传递到调用处
129 0