• JavaScript – Async Iterator & Generator


    前言

    要看懂这篇请先看下面几篇

    JavaScript – Iterator

    JavaScript – Generator Function

    JavaScript – Promise

    JavaScript – 用 Generator 运行异步函数 & await async

    Async Iterator (es2018)

    es6 推出的 Iterator + for...of 非常好用, 但是它只能执行同步代码. 不支持异步编程.

    顾名思义 Async Iterator 就是 Iterator 的 Async 版本. 它支持异步编程.

    我们来看看 sync 和 async Iterator 的对比

    sync Iterable

    const iterable: Iterable<string> = {
      [Symbol.iterator]() {
        let index = 0;
        return {
          next() {
            index++;
            if (index === 10) {
              return {
                done: true,
                value: '',
              };
            }
            return { done: false, value: 'value' + index };
          },
        };
      },
    };
    
    for (const value of iterable) {
      console.log('value', value);
    }

    async Iterable

    const asyncIterable: AsyncIterable<string> = {
      [Symbol.asyncIterator]() {
        let index = 0;
        return {
          async next() {
            return new Promise((resolve) => {
              setTimeout(() => {
                index++;
                if (index === 10) {
                  resolve({
                    done: true,
                    value: '',
                  });
                }
                return resolve({ done: false, value: 'value' + index });
              }, 1000);
            });
          },
        };
      },
    };
    (async () => {
      const asyncIterator = asyncIterable[Symbol.asyncIterator]();
      const { value, done } = await asyncIterator.next();
      console.log([value, done]);
      for await (const value of asyncIterable) {
        console.log('value', value);
      }
    })();

    和 sync iterable 的区别是

    1. 属性是 Symbol.asyncIterator

    2. iterator next 返回的是一个 promise, promise 的返回才是 done 和 value

    3. 遍历的方式是 for await ... of

    你可能会认为, sync iterable 也可以返回 promise 丫.

    的确. 在 JavaScript – 用 Generator 运行异步函数 & await async 里有提到如何用 Generator + Iterator + Promise + 自执行 Generator 来实现异步编程 (async await 语法糖的背后的原理)

    它的 iterator next value 返回的就是 promise. 但不要忘了, 还有 done 属性呢? 这个总不能返回 Promise 了丫. 所以还是有细微区别的. 

    Async Generator (es2018)

    和 Async Iterator 一样概念. Generator 也有 Async 版本.

    function delayAsync(time: number, value: string) {
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve(value);
        }, time);
      });
    }
    async function* myGenerator() {
      yield delayAsync(1000, 'a');
      console.log('do something');
      yield delayAsync(1000, 'b');
    }
    (async () => {
      const asyncIterator = myGenerator();
      for await (const value of asyncIterator) {
        console.log(value);
      }
      // 1000ms after log a
      // do something
      // another 1000ms after log b
    })();

    和 sync Generator 的区别是

    1. async function* 多了 async 关键字开头

    2. yield 返回 Promise

    3. 可以用 for await...of 遍历

    for...of + Promise.all 对比 for await...of

    当有一堆 promises 想 loop 的时候, 在 for await...of 出现前. 通常是搭配 Promise.all 来使用的

    const promises = [delayAsync(1000, 'a'), delayAsync(2000, 'b')];
    
    (async () => {
      for (const value of await Promise.all(promises)) {
        console.log(value);
      }
    
      for await (const value of promises) {
        console.log(value);
      }
    })();

    几时知识点:

    1. 当 delayAsync 调用时, setTimeout 马山就执行了. 所以下面这 2 个 timeout 是一起 start 的哦

    const promises = [delayAsync(1000, 'a'), delayAsync(2000, 'b')];

    2. 

    for (const value of await Promise.all(promises)) {
        console.log(value);
    }

    await Promise.all 返回 array 后才进入 for...of. 所以在 2 秒钟后 log a 和 log b 会马上执行 (同步, 中间没有间隔时间)

    3.

    for await (const value of promises) {
      console.log(value);
    }

    和 for...of 不同, 它会先去 loop, 所以会先拿出第一个 promise, 等待. 1 秒钟后就会执行 log a.

    然后再拿第 2 个 promise. 这时 promise2 已经过去 1 秒了, 所以再 1 秒钟后就会只是 log b.

    一定要搞清楚它们执行的顺序和时机哦.

  • 相关阅读:
    阿里开源混沌工程工具 ChaosBlade
    十天入门java教程 Day01
    如何破解IDEA
    Locust压力测试使用总结
    python+requests接口自动化测试框架实例详解教程
    一个完整的性能测试流程
    jmeter测试报告汉化及脚本编写
    tomcat的日志文件权限与启动用户的权限不一致
    Linux下部署开源版“禅道”项目管理系统
    ELK原理与介绍
  • 原文地址:https://www.cnblogs.com/keatkeat/p/16298907.html
Copyright © 2020-2023  润新知