同步迭代与异步迭代

432 阅读1分钟

同步迭代(Symbol.iteratorfor of

一个 Object 要想是可迭代的,需要有 Symbol.iterator 属性

function buildIterator() {
  const timeList = [2000, 1000, 3000, 5000, 4000]
  return {
    next() {
      return {
        done: timeList.length === 0,
        value: timeList.shift()
      }
    }
  }
}

function testSync() {
  const begin = Date.now()
  console.log(Date.now() - begin, 'begin')
  const iteratableObj = {
    [Symbol.iterator]: buildIterator
  }
  for (let item of iteratableObj) {
    console.log(Date.now() - begin, item)
  }
  console.log(Date.now() - begin, 'end')
}

testSync()

运行结果:

image.png

异步迭代(Symbol.asyncIteratorfor await...of

一个 Object 要想是异步可迭代的,需要有 Symbol.asyncIterator 属性

实现如下功能:给定一个数组 [2000, 1000, 3000, 5000, 4000],按顺序按值对应的时长打印出来

function buildAsyncIterator() {
  const timeList = [2000, 1000, 3000, 5000, 4000]
  return {
    next() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve({
            done: timeList.length === 0,
            value: timeList.shift()
          })
        }, timeList[0])
      })
    }
  }
}

async function testAsync() {
  const begin = Date.now()
  console.log(Date.now() - begin, 'begin')
  const asyncIteratableObj = {
    [Symbol.asyncIterator]: buildAsyncIterator
  }
  for await (let item of asyncIteratableObj) {
    console.log(Date.now() - begin, item)
  }
  console.log(Date.now() - begin, 'end')
}

testAsync()

运行结果:

image.png

Promise(async awaitfor of

当然不用异步迭代也能实现

function buildPromise(time) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(time)
    }, time)
  })
}

async function testPro() {
  const begin = Date.now()
  console.log(Date.now() - begin, 'begin')
  const timeList = [2000, 1000, 3000, 5000, 4000]
  for (item of timeList) {
    const time = await buildPromise(item)
    console.log(Date.now() - begin, time)
  }
  console.log(Date.now() - begin, 'end')
}

testPro()

运行结果:

image.png

参考

for-await-of and synchronous iterables

Async iteration and generators

Asynchronous iteration