迭代器模式和生成器模式

迭代器模式(Interator)

作用

  • 是为各种数据结构,提供一个统一的、简便的访问接口
  • 使得数据结构的成员能够按某种次序排列
  • 是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费

默认已经实现iterable接口的类型:

  • 字符串
  • 数组
  • 映射
  • 集合
  • arguments对象
  • NodeList等DOM集合类型

可迭代对象的原生语言特性包括:

  • for-of循环
  • 数组解构
  • 扩展操作符
  • Array.from()
  • 创建集合
  • 创建映射
  • Promise.all()接收由期约组成的可迭代对象
  • Promise.race()接收有期约组成的可迭代对象
  • yield*操作符,在生成器中使用

小demo

每个可迭代对象可以生成多个迭代器,并且互相不影响

let arr = ['foo','bar','arr']
//生成arr的迭代器
let iter = arr[Symbol.iterator]()
let iter1 = arr[Symbol.iterator]()
//执行迭代
console.log(iter.next());//foo
console.log(iter1.next());//foo
console.log(iter.next());//bar
console.log(iter1.next());//bar
console.log(iter.next());//arr
console.log(iter1.next());//arr

//还可以用于for-of循环
let arr1 = [1,2,3]
let iter2 = arr1[Symbol.iterator]()
for(let item of iter2){
console.log(item)
}//1 2 3

自定义可迭代对象

 //自定义可迭代对象
        class Counter{
            constructor(limit){
                this.limit = limit
            }
            [Symbol.iterator](){
                let count =1,
                limit = this.limit
                return{
                    next(){
                        if(count<=limit){
                            return {done:false,value: count++}
                        }else{
                            return {done:true,value: undefined}
                        }
                    }
                }
            }
        }
        let counter = new Counter(4)
        for(let item of counter){
            console.log(item);
        }

提前终止迭代器

当迭代一个可迭代对象的时候,不想让它迭代完才结束,我们需要达到某个条件的时候就结束迭代
可能的情况包括:

  • for-of循环通过break,continue,return或throw提前退出
  • 解构操作

数组不可提前结束

//提前终止迭代器
        let arr = [1,2,3,4,5]
        let iter = arr[Symbol.iterator]()
        for(let item of iter){
            console.log(item);  //1 2 3
            if(item>2){
                break
            }
        }
        for(let item of iter){
            console.log(item);   //4 5
        }

生成器模式(Generator)

特点

1、函数生成器特点是函数名前面有一个‘*’

2、通过调用函数生成一个控制器

3、调用next()方法开始执行函数

4、遇到yield函数将暂停

5、再次调用next()继续执行函数

生成器函数


        //生成器
        function* genarator(){
            console.log(1);
            yield 1;
            console.log(2);
            yield 2;
            console.log(3);
            yield 3;
        }
        let gen = genarator()
        console.log(gen.next());
        console.log(gen.next());
        console.log(gen.next());
        console.log(gen.next());
        

在这里插入图片描述

生成器可作为默认迭代器

//生成器默认迭代器
        class Foo{
            constructor(){
                this.values = [1,2,3]
            }
            //生成器函数
            *[Symbol.iterator](){
            //yield* 实际上将一个可迭代对象序列化为一连串可以单独产出的值
                yield* this.values
            }
        }
        const f = new Foo()
        for(let item of f){
            console.log(item);
        }

提前终止生成器

  • next()
  • return()
  • throw()

通过return()进入关闭状态,就无法恢复了,后续通过next()会显示done:true状态,提供的任何返回值都不会被存储或传播

		function* generatorFn(){
            for (let x of [1,2,3]){
                yield x;
            }
        }
        const g = generatorFn()
        console.log(g.next());    //{value: 1,done: false}
        console.log(g.return(4)); // {value: 4,done: true}
        console.log(g.next()); //{value: undefined, done: true}

throw()放在暂停的时候将一个提供的错误注入到生成器对象中,如果错误未被处理,生成器就会关闭

function* generatorFn(){
            for (let x of [1,2,3]){
              yield x;
            }
        }
        let g = generatorFn();
        console.log(g);   //generatorFn (<suspended>)
        try{
        g.throw('foo')
        }catch(e){
        console.log(e)  //foo
        }
        console.log(g);    //generatorFn (<closed>)

如果生成器内部处理这个错误则不会关闭

function* generatorFn(){
            for (let x of [1,2,3]){
              try{
                  yield x;
              } catch(e){}
            }
        }
        let g = generatorFn();
        console.log(g.next());   //{value: 1,done: false}
        //注入一个错误,在生成器中被捕获抛出,所以
        g.throw('foo')
        console.log(g.next());    //{value: 3,done: false}

参考书籍:《javaScript高级程序设计(第四版)》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值