异步迭代器(async Iterator)

  1. 同步迭代器
  2. 异步迭代器
  3. for await...of
  4. 异步生成器函数
  5. yield*语句

1.同步迭代器

  • 一般的迭代器生成函数在被调用后会返回一个迭代器对象,能够去调用迭代器上的next办法
  • next办法一旦执行,就必须同步地失去一个状态对象,{value,done}

    //迭代器生成函数function makeIterator(arr) {  var nextIndex = 0;  return {      next() {          return nextIndex < arr.length ?              { value: arr[nextIndex++], done: false } :              { value: undefined, done: true }      }  }}//调用并遍历const arr = [1]let iter = makeIterator(arr)console.log(iter.next()) //{value: 1, done: false}console.log(iter.next());//{value: undefined, done: true}

2.异步迭代器

让next返回的value是一个Promise对象,用then链式解决

//迭代器生成函数function makeIterator(arr) {    var nextIndex = 0;    let delay = 4000    return {        next() {            let res = nextIndex < arr.length ?                {                    value: new Promise(resolve => setTimeout(() => resolve(arr[nextIndex++]), delay -= 1000)),                    done: false                }                : { value: undefined, done: true }            return res        }    }}//调用并遍历const arr = [1, 2]let iter = makeIterator(arr)iter.next().value.then(val => console.log(val)) //1iter.next().value.then(val => console.log(val));//2iter.next().value.then(val => console.log(val));//undefined
这种办法只是让value异步执行,done的值并不是异步产生的,并且执行了流程不清晰,语义比拟绕

next间接返回一个Promise,用then的链式解决异步

//迭代器生成函数function asyncIterator(arr) {    var nextIndex = 0    return {        [Symbol.asyncIterator]() {            return {                next() {                    if (nextIndex < arr.length) {                        return new Promise(resolve => {                            setTimeout(() => resolve({ value: arr[nextIndex++], done: false }), 1000)                        })                    } else {                        return { value: undefined, done: true }                    }                }            }        }    }}//链式执行const asyncIterable = asyncIterator([1, 2])const asyncIter = asyncIterable[Symbol.asyncIterator]()asyncIter    .next()    .then(val1 => {        console.log(val1);        return asyncIter.next()    })    .then(val2 => {        console.log(val2);        return asyncIter.next()    })    .then(val3 => {        console.log(val3);    })//{value: 1, done: false}//{value: 2, done: false}//{value: undefined, done: true}
既然asyncIter返回的是一个Promise,那么执行能够用async改写,能失去统一的后果
async function runner() {    const asyncIterable = asyncIterator([1, 2])    const asyncIter = asyncIterable[Symbol.asyncIterator]()    let val1 = await asyncIter.next()    console.log(val1);    console.log(await asyncIter.next());    console.log(await asyncIter.next());}

3 for await...of

依据下面的迭代器生成函数,Symbol.asyncIterator是一个异步迭代器的接口,返回一个迭代器对象,能够用for await...of去遍历这个接口

async function runner() {    for await (const i of asyncIterator([1, 2])) {        console.log(i);    }}runner()//1//2
  • asyncIterator([1, 2])返回一个对象,这个对象领有异步迭代器接口,能返回一个异步迭代器对象
  • 这个对象的异步迭代器的next办法被for...of循环主动调用会失去一个Promise 对象
  • await用来解决这个 Promise 对象,在resolve之后把失去的值i传入for...of的循环体
遍历出错会终止for await...of,并报错
能够将for await..of放在try中,用catch捕捉谬误

4.异步生成器函数

同步的生成器函数会生成一个同步迭代器,那么异步生成器则生成异步迭代器
作用
Generator 函数解决同步操作和异步操作时,可能应用同一套接口

特点
异步生成器函数就是async和Generator的联合

function promise(data, delay) {    return new Promise(resolve => {        setTimeout(() => {            resolve(data)        }, delay)    })}function printHello() {    return promise("Hello", 1000)}function printWorld() {    return promise("World", 1000)}async function* gene() {    yield printHello()    yield printWorld()}let iter = gene()iter.next()    .then(val => { console.log(val); })//{value:"Hello",done:false}
  • 异步的生成器函数返回一个迭代器对象,调用next办法,返回的是一个Promise,用then能取到状态对象
  • 同步的生成器函数返回一个迭代器对象,调用next办法,间接返回状态对象,状态对象中的value是一个Promise
  • 应用for await...of能够异步的遍历同步迭代器,然而只有value是异步的,done的生成依然是同步的

    async function runner() {  for await (const i of iter) {      console.log(i);  }}runner()
    不论Generator函数前是否有async都会别离提早1000ms打印Hello与World

await 和 yield能够同时呈现在异步Generator函数中

async function* readLines(path) {  let file = await fileOpen(path);  try {    while (!file.EOF) {      yield await file.readLine();    }  } finally {    await file.close();  }}
await前面的操作返回一个Promise对象,将内部操作产生的值输出函数外部
yield命令会返回一个Promise,作为每个next暂停的地位,将函数外部的值输入
  • async函数和异步Generator函数都是对异步操作的封装
  • async函数自带执行器
  • 异步Generator函数能够用for await...of去遍历

函数就能够分为四类

  1. 一般函数
  2. async函数
  3. Generator函数
  4. 异步Generator函数

5. yield* 语句

yield* 后能够跟一个Generator函数,将其语句开展到异步生成器内

function* gene1() {    yield 'a'    yield 'b'    console.log(0);}async function* gene2() {    yield* gene1()    yield 'c';}async function runner() {    for await (const i of gene2()) {        console.log(i);    }}runner()//"a"//"b"//0//"c"