美文网首页
ES6学习笔记(27)之 异步遍历器

ES6学习笔记(27)之 异步遍历器

作者: 苦苦修行 | 来源:发表于2019-09-30 10:22 被阅读0次

参考:ECMAScript 6 入门

同步遍历器的问题

前面讲的遍历器调用next方法后会立即返回一个这样的对象{value: '随你是啥', done: false/true}
如果 yield 后面的表达式是同步的还好说,value 就是表达式的值;如果 yield 后面的表达式是异步的会怎样?调用next方法还是会立即返回像上面的那种对象,但是 value 的值是 promise 对象。

解决方案

为了解决这个问题,ES2018 引入了“异步遍历器”(Async Iterator),为异步操作提供原生的遍历器接口。
在异步遍历器中,next方法返回的是promise对象,在它的 resolve 结果中返回{value: 'resolve 的值', done: false/true}对象

异步遍历的接口

同步遍历器的接口部署在Symbol.iterator属性上面。
异步遍历器接口,部署在Symbol.asyncIterator属性上面。

两种遍历接口遍历异步方法的不同

同步:iterator.next().value.then()
异步:asyncIterator.next().then()

for await...of

同步遍历器使用 for...of,异步遍历器使用 for await...of,举例

// 因为有 await,该方法还实现了异步方法的同步执行
async function f() {
  for await (const x of createAsyncIterable(['a', 'b'])) {
    console.log(x);
  }
}
// a
// b

异步遍历接口的好处

for await...of循环也可以用于同步遍历器。
异步遍历器的设计目的之一,就是处理同步操作和异步操作时,能够使用同一套接口。

异步 Generator 函数

就像 Generator 函数返回一个同步遍历器对象一样,异步 Generator 函数的作用,是返回一个异步遍历器对象。
在语法上,异步 Generator 函数就是async函数与 Generator 函数的结合。

async function* gen() {
  yield 'hello';
  yield 'world';
}
const genObj = gen();
genObj.next().then(x => console.log(x));
// { value: 'hello', done: false }
genObj.next().then(x => console.log(x));
// { value: 'world', done: false }

在上面的例子中,因为是异步的,所以调用next方法时返回promise对象。另外两个next调用 then 时,不能保证哪个先执行(假设yield后面是执行完所用时间不确定的异步方法)

function fetchRandom() {
  const url = 'https://www.random.org/decimal-fractions/'
    + '?num=1&dec=10&col=1&format=plain&rnd=new';
  return fetch(url);
}

async function* asyncGenerator() {
  console.log('Start');
  const result = await fetchRandom(); // (A)
  yield 'Result: ' + await result.text(); // (B)
  console.log('Done');
}

const ag = asyncGenerator();
ag.next().then(({value, done}) => {
  console.log(value);
})

上面代码中,ag是asyncGenerator函数返回的异步遍历器对象。调用ag.next()以后,上面代码的执行顺序如下。

  1. ag.next()立刻返回一个 Promise 对象。
  2. asyncGenerator函数开始执行,打印出Start。
  3. await命令返回一个 Promise 对象,asyncGenerator函数停在这里。
  4. A 处变成 fulfilled 状态,产生的值放入result变量,asyncGenerator函数继续往下执行。
  5. 函数在 B 处的yield暂停执行,一旦yield命令取到值,ag.next()返回的那个 Promise 对象变成 fulfilled 状态。
  6. ag.next()后面的then方法指定的回调函数开始执行。该回调函数的参数是一个对象{value, done},其中value的值是yield命令后面的那个表达式的值,done的值是false。

比对上面两个例子

可以发现,它们的调用方式都是异步遍历器对象.next().then()。不同的是,没有await的,异步方法的执行顺序无法保证,有await的 ,按顺序执行异步方法。

相关文章

  • ES6学习笔记(27)之 异步遍历器

    参考:ECMAScript 6 入门 同步遍历器的问题 前面讲的遍历器调用next方法后会立即返回一个这样的对象{...

  • string

    es6 字符串的新增属性。学习笔记此博文 字符串的遍历器的接口。 includes(),startsWith(),...

  • 27. 异步遍历器

    仅为方便个人查询使用来源:http://es6.ruanyifeng.com/#docs/async-iterat...

  • ES6中Generator函数的用法

    Generator 函数是 ES6 提供的一种异步编程解决方案,也是遍历器生成函数,语法行为与传统函数完全不同。 ...

  • Generator(生成器)和async await

    1、generator generator是ES6实现的标准。generator 函数返回一个遍历器对象遍历器对象...

  • ES6 字符串的扩展

    字符串的遍历器接口 ES6为字符串添加了遍历器接口,使得字符串能够被for...of循环遍历 includes()...

  • 三.字符串的扩展

    字符串的遍历器接口 es6为字符串添加了遍历器接口,使得字符串可以被 for...of循环遍历。 includes...

  • ES6常用特性(二)

    一、字符串的扩展 字符串的遍历器接口ES6为字符串添加了遍历器接口,可以使用for...of 循环遍历for(le...

  • String

    字符串的遍历器接口 ES6为字符串添加了遍历器接口,使得字符串可以被for...of循环遍历 模版字符串 模版字符...

  • 3. 字符串的扩展

    字符串的遍历接口 ES6为字符串添加了遍历器接口,使得字符串可被for..of循环遍历 for...of遍历字符串...

网友评论

      本文标题:ES6学习笔记(27)之 异步遍历器

      本文链接:https://www.haomeiwen.com/subject/biecuctx.html