ES6迭代器和生成器

迭代器

  • 迭代器(Iterator)是一种接口((Iterator)接口就是数据类型中的Sysmbol.iterator的属性,如下图),为各种不同的数据结构提供统一的访问机制。

在这里插入图片描述
在这里插入图片描述

var arr = ["江流", "心猿", "木龙", "刀圭", "意马"];
//使用for...of遍历数组
for (let value of arr) {
    console.log(value);
}

在这里插入图片描述

工作原理

  1. 创建一个指针对象,指向当前数据结构的起始位置
  2. 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
  3. 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
  4. 每调用next方法返回一个包含valuedone属性的对象
    注:需要自定义遍历数据的时候,要想到迭代器
var arr = ["江流", "心猿", "木龙", "刀圭", "意马"];
//查看next方法
let iterator = arr[Symbol.iterator]();
console.log(iterator);
//调用对象的next方法
console.log((iterator.next()));//{value: '江流', done: false}
console.log((iterator.next()));//{value: '木龙', done: false}
console.log((iterator.next()));//{value: '刀圭', done: false}
console.log((iterator.next()));//{value: '刀圭', done: false}
console.log((iterator.next()));//{value: '意马', done: false}
console.log((iterator.next()));//越界

在这里插入图片描述

迭代器的应用-自定义遍历数据

  • 需求: 通过for...of遍历一个对象中指定的数组元素,且只返回数组元素。
const xiyou = {
    name: "西游记",
    member: [
        "江流",
        "心猿",
        "木龙",
        "刀圭",
        "意马"
    ],
    [Symbol.iterator]() {
        // 索引变量
        let index = 0;
        // 
        return {
            next: () => {
                if (index < this.member.length) {
                    const result = { value: this.member[index], done: false };
                    // 下标自增
                    index++;
                    // 返回结果
                    return result;
                }
                else {
                    return { value: undefined, done: true };
                }
            }
        }
    }

}
for(let value of xiyou)
{
    console.log(value);
}

在这里插入图片描述

生成器

  • 生成器函数是ES6提供的一种异步编程解决方案
  • 每次也是通过Iterator.next()方法调用
  • 可以通过for...of进行遍历
  • yield是函数代码分割符
function * gen(){
    yield "江流";
    yield "心猿";
    yield "意马";
}
// next指针方法访问

let iteratot = gen();
console.log(iteratot.next());//{ value: '江流', done: false }
console.log(iteratot.next());//{ value: '心猿', done: false }  
console.log(iteratot.next());//{ value: '意马', done: false }  
console.log(iteratot.next());//越界

// for...of遍历
for(let value of gen())
{
    console.log(value);
}

在这里插入图片描述

生成器函数参数

  • 该函数可以像正常函数一样传入形参
  • next方法可以传入实参,实参会作为整个yield 语句的返回值
  • 第二次调用next方法会作为第一次整个yield 语句的返回值
  • 第三次调用next方法会作为第二次整个yield 语句的返回值
  • 以此类推
function * gen(arg){
    console.log(arg);//正常打印形参
    let one = yield "江流";
    console.log(one);//1
    let tow = yield "心猿";
    console.log(tow);//2
    let three = yield "意马";
    console.log(three);//3
}

// next指针方法访问
let iteratot = gen(0);//传入形参
console.log(iteratot.next());//
console.log(iteratot.next(1));//作为第一个yield语句的返回值
console.log(iteratot.next(2));//作为第二个yield语句的返回值
console.log(iteratot.next(3));//作为第三个yield语句的返回值

在这里插入图片描述

生成器函数实例

  • 第一个需求: 1s 后控制台输出 111 2s后输出 222 3s后输出333

ES5中使用定时器套回调函数的方法的写法:

setTimeout(() => {
    console.log((111));
    setTimeout(() => {
        console.log(222);
        setTimeout(() => {
            console.log(333);
        }, 3000);
    }, 2000)
}, 1000);

如果有很多的回调函数,就会不断在回调函数内部叠加,形成回调地狱

ES6使用生成器函数的写法:

function one() {
    setTimeout(() => {
        console.log(111);
        iterator.next();
    }, 1000);
}
function two() {
    setTimeout(() => {
        console.log(111);
        iterator.next();
    }, 2000);
}
function three() {
    setTimeout(() => {
        console.log(111);
        iterator.next();
    }, 3000);
}
function* gen() {
    yield one();
    yield two();
    yield three();
}
// 调用生成器函数

let iterator = gen();
iterator.next();

在这里插入图片描述

**第二个需求:**模拟异步获取 用户数据 订单数据 商品数据

function getUsers(){
    setTimeout(() => {
        let data = "用户数据";
        // 调用next方法,并将数据传入
        iterator.next(data);
    }, 1000);
}

function getOrders(){
    setTimeout(() => {
        let data = "订单数据";
        iterator.next(data);
    }, 1000);
}

function getGoods(){
    setTimeout(() => {
        let data = "商品数据";
        iterator.next(data);
    }, 1000);
}
function * gen(){
    let users = yield getUsers();
    console.log(users);
    let orders = yield getOrders();
    console.log(orders);
    let goods = yield getGoods();
    console.log(goods);
}

// 调用生成器函数
let iterator = gen();
iterator.next();

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值