ES6(5):迭代器、生成器

àì夳堔傛蜴生んèń 2022-12-24 11:55 294阅读 0赞

文章目录

      • 一、迭代器
          1. ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费
          1. 原生具备 iterator 接口的数据(可用 for of 遍历)
          1. 工作原理
          1. 示例:
          1. 自定义遍历数据 示例:
      • 二、生成器
          1. 特殊在:
          1. 基本用法
          1. 生成器函数参数
          1. 生成器函数实例
          • 实例1:1s 后控制台输出 111 2s后输出 222 3s后输出 333
          • 实例2:模拟获取 用户数据 订单数据 商品数据

一、迭代器

迭代器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提
供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。

1. ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费

2. 原生具备 iterator 接口的数据(可用 for of 遍历)

  • Array
  • Arguments
  • Set
  • Map
  • String
  • TypedArray
  • NodeList

3. 工作原理

  • 创建一个指针对象,指向当前数据结构的起始位置
  • 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
  • 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
  • 每调用 next 方法返回一个包含 value 和 done 属性的对象
  • 注: 需要自定义遍历数据的时候,要想到迭代器。

4. 示例:

  1. //声明一个数组
  2. const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];
  3. //使用 for...of 遍历数组
  4. for(let v of xiyou){
  5. console.log(v);
  6. }

在这里插入图片描述

  1. //使用迭代器
  2. let iterator = xiyou[Symbol.iterator]();
  3. //调用对象的next方法
  4. console.log(iterator.next());
  5. console.log(iterator.next());
  6. console.log(iterator.next());
  7. console.log(iterator.next());
  8. console.log(iterator.next());

在这里插入图片描述

5. 自定义遍历数据 示例:

  1. //声明一个对象
  2. const banji = {
  3. name: "终极一班",
  4. stus: [
  5. 'xiaoming',
  6. 'xiaoning',
  7. 'xiaotian',
  8. 'knight'
  9. ],
  10. [Symbol.iterator]() {
  11. //索引变量
  12. let index = 0;
  13. //保存this
  14. let _this = this;
  15. return {
  16. next: function () {
  17. if (index < _this.stus.length) {
  18. const result = { value: _this.stus[index], done: false };
  19. //下标自增
  20. index++;
  21. //返回结果
  22. return result;
  23. }else{
  24. return { value: undefined, done: true};
  25. }
  26. }
  27. };
  28. }
  29. }
  30. //遍历这个对象
  31. for (let v of banji) {
  32. console.log(v);
  33. }

在这里插入图片描述

二、生成器

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

1. 特殊在:

  • 字面量(函数声明 / 函数表达式)的关键字 function 后面多了一个 * ,* 前后允许有空白字符。 * 的位置没有限制

    function * gen(){

    }

    function *gen(){

    }

    function* gen(){

    }

  • 函数体中多了 yield 运算符,yield 相当于函数的暂停标记,也可以认为是函数的分隔符

    function * gen(){

    1. yield 'a';
    2. yield 'b';
    3. yield 'c';

    }

2. 基本用法

  1. function * gen(){
  2. console.log(111);
  3. yield 'a';
  4. console.log(222);
  5. yield 'b';
  6. console.log(333);
  7. yield 'c';
  8. console.log(444);
  9. }
  10. let iterator = gen();
  11. iterator.next();
  12. iterator.next();
  13. iterator.next();
  14. iterator.next();

在这里插入图片描述

  1. function * gen(){
  2. console.log(111);
  3. yield 'a';
  4. console.log(222);
  5. yield 'b';
  6. console.log(333);
  7. yield 'c';
  8. console.log(444);
  9. }
  10. let iterator = gen();
  11. console.log(iterator.next());
  12. console.log(iterator.next());
  13. console.log(iterator.next());
  14. console.log(iterator.next());

在这里插入图片描述

  • 在调用 gen() 时,函数体中的逻辑并不会执行(控制台没有输出)
  • 生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到
    yield 语句后的值
  • 第一次调用 iterator.next(),函数开始执行,直到遇到第一个 yield 表达式为止
  • 第二次调用 iterator.next(),函数从上次 yield 表达式停下的地方,一直执行到下一个 yield 表达式以此类推,一直执行到函数结束 (如果有return语句,就执行到return 语句)
  • 第n次调用 iterator.next(),函数已经运行完毕,next方法返回对象的value属性为undefined,done属性为true

3. 生成器函数参数

  1. function * gen(arg){
  2. console.log(arg);
  3. let one = yield 111;
  4. console.log(one);
  5. let two = yield 222;
  6. console.log(two);
  7. let three = yield 333;
  8. console.log(three);
  9. }
  10. //执行获取迭代器对象
  11. let iterator = gen('AAA');
  12. console.log(iterator.next());
  13. //next方法可以传入实参
  14. console.log(iterator.next('BBB'));
  15. console.log(iterator.next('CCC'));
  16. console.log(iterator.next('DDD'));

在这里插入图片描述
第二次调 iterator.next() 方法传入的实参,将作为第一个 yield 语句的返回结果。以此类推。

4. 生成器函数实例

实例1:1s 后控制台输出 111 2s后输出 222 3s后输出 333
  1. // 回调地狱
  2. setTimeout(() => {
  3. console.log(111);
  4. setTimeout(() => {
  5. console.log(222);
  6. setTimeout(() => {
  7. console.log(333);
  8. }, 3000);
  9. }, 2000);
  10. }, 1000);

用迭代器的写法:

  1. function one(){
  2. setTimeout(()=>{
  3. console.log(111);
  4. iterator.next();
  5. },1000)
  6. }
  7. function two(){
  8. setTimeout(()=>{
  9. console.log(222);
  10. iterator.next();
  11. },2000)
  12. }
  13. function three(){
  14. setTimeout(()=>{
  15. console.log(333);
  16. iterator.next();
  17. },3000)
  18. }
  19. function * gen(){
  20. yield one();
  21. yield two();
  22. yield three();
  23. }
  24. //调用生成器函数
  25. let iterator = gen();
  26. iterator.next();

在这里插入图片描述

实例2:模拟获取 用户数据 订单数据 商品数据
  1. //模拟获取 用户数据 订单数据 商品数据
  2. function getUsers(){
  3. setTimeout(()=>{
  4. let data = '用户数据';
  5. //调用 next 方法, 并且将数据传入
  6. iterator.next(data);
  7. }, 1000);
  8. }
  9. function getOrders(){
  10. setTimeout(()=>{
  11. let data = '订单数据';
  12. iterator.next(data);
  13. }, 1000)
  14. }
  15. function getGoods(){
  16. setTimeout(()=>{
  17. let data = '商品数据';
  18. iterator.next(data);
  19. }, 1000)
  20. }
  21. function * gen(){
  22. let users = yield getUsers();
  23. console.log(users);
  24. let orders = yield getOrders();
  25. console.log(orders);
  26. let goods = yield getGoods();
  27. console.log(goods);
  28. }
  29. //调用生成器函数
  30. let iterator = gen();
  31. iterator.next();

在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,294人围观)

还没有评论,来说两句吧...

相关阅读

    相关 装饰生成器

    生成器和迭代器类似,都是用来提供遍历的一种特殊数据结构。 生成器不会占用大量的内存,只在遍历的时候会占用生成值的内存 生成器的特点是使用yield

    相关 生成器

    在学习`迭代器(Iterator)`之前,我们需要理解一下的几个问题 什么是迭代? 从一个数据集合中按照一定的顺序,不断的取出数据的过程。 迭代和遍历有什么区别? 迭代

    相关 生成器

    迭代器和生成器 迭代和可迭代 什么是迭代(iteration)?  如果给定一个list或tuple,我们要想访问其中的某个元素,我们可以通过下标来,如果我们想