JS迭代器Iterator及生成器Generator

        迭代器(iterator),是确使用户可在容器对象(container,例如链表或数组)上遍访的对象,使用该接口无需关心对象的内部实现细节。

        在JavaScript中,迭代也是一个具体的对象,这个对象需要符合迭代器协议(Iterator protocol):实现一个特定的next方法。

next函数实现调用时返回一个固定对象,{value:'value',done:'boolean'},如果迭代器可以产生序列中的下一个值,则done为false,反之done属性值为true,此时value属性值可以省略。具体的class实现原理如下:

// 创建可迭代类对象
class creatIterator {

  constructor(obj) {
    this.keys = Object.keys(obj);
  };

  [Symbol.iterator]() {
    let index = 0;
    return {
      next() {
        if (index < keys.length) {
          return {
            done: false,
            value: obj[keys[index++]]
          }
        } else {
          return {
            done: true,
            value: undefined
          }
        }
      }
    }
  }
}

 在创建的实现迭代器的类中,按照迭代器定义规范实现next函数,返回特定的结果。

迭代器运用的场景--for...of,展开语法,yield,解构赋值

  • 创建一些对象时:new Map([Iterable])、new WeakMap([iterable])、new Set([iterable])、new WeakSet([iterable]);
  • 一些方法的调用:Promise.all(iterable)、Promise.race(iterable)、Array.from(iterable);
  • 在for...of中要求遍历的对象是可迭代的,无法直接遍历对象,可通过将对象处理成可迭代对象,实现for...of遍历操作。构造函数实现方法:
  • // 传入一个对象,返回可迭代对象
    function CreatIteratorFn(obj) {
      this.keys = Object.keys(obj);
      let index = 0;
      return {
        next() {
          if (index < keys.length) {
            return {
              done: false,
              value: obj[keys[index++]]
            }
          } else {
            return {
              done: true,
              value: undefined
            }
          }
        }
      }
    }
    
    const arr = [1, 2, 3, 4, 5]
    const obj = {
      age: 18,
      name: 'alison'
    }
    const demo2 = CreatIteratorFn(obj);
    console.log('demo2', demo2.next()); //demo2 { done: false, value: 18 }

    迭代器的中断----

  • class creatIterator {
      constructor(obj) {
        this.obj = obj;
        this.keys = Object.keys(obj);
      };
      [Symbol.iterator]() {
        let index = 0;
        return {
          next: () => {
            if (index < this.keys.length) {
              return {
                done: false,
                value: this.obj[this.keys[index++]]
              }
            } else {
              return {
                done: true,
                value: undefined
              }
            }
          },
          return: () => {
            console.log("迭代器提前终止了~")
            return {
              done: true,
              value: undefined
            }
          }
        }
      }
    }

生成器----generator

  • 生成器是ES6中新增的一种控制函数、使用的方案,它可以让我们更加灵活的控制函数什么时候执行、暂停执行等。

  • 生成器函数与普通函数的写法不同点在于需要在function关键字后面添加一个符号 *。

  • 生成器函数可以通过yield控制函数的执行流程。

  • 生成器函数返回的是一个生成器对象,对象拥有next方法,通过调用next方法执行函数的代码段。

 利用生成器函数模拟服务器请求:

// 模拟请求函数  匹配正确网址
function request(url) {
  const urlRule = /^w{3}\.{1}.+\.{1}(com|cn|org){1}\b$/;
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (urlRule.test(url)) {
        resolve('网址匹配成功,正在解析网络地址')
      } else {
        reject('输入网址非法,请重新输入');
      }
    }, 2000)
  })
}

// 封装生成器函数,执行异步代码
function* execGen(fn) {
  yield request('www.baidu1.com')
  yield request('www.baidu2.com')
  yield request('wwwbaidu3.com')
}

const gen = execGen();


console.log(gen.next().value.then(res => {
  console.log(res);
}).catch(err => console.log(err)));


console.log(gen.next().value.then(res => {
  console.log(res);
}).catch(err => console.log(err)));


console.log(gen.next().value.then(res => {
  console.log(res);
}).catch(err => console.log(err)));

        生成器实际上是一种特殊的迭代器,通过将函数编写为生成器函数可以实现分段调用,yield关键字作为函数分段执行的关键字,同时生成器函数也可以调用return方法结束函数的执行。throw关键字在生成器函数中也同样适用,可以捕获生成器函数内部的异常。

你可能感兴趣的:(javascript,前端,java)