美文网首页
第八章 迭代器Iterator和生成器Generator

第八章 迭代器Iterator和生成器Generator

作者: monkeyfly36 | 来源:发表于2021-08-30 19:14 被阅读0次

    1.迭代器是一种特殊的对象,它有一个next()方法;
    每次调用都会返回一个结果对象->{done: xxx, value: xxx},它有done和value两个属性。

    function createIterator(arr) {
      let i  = 0
      return {
        next() {
          let done = i >= arr.length
          let value = done ? undefined : arr[i++]
          return { done, value }
        }
      }
    }
    
    let iterator = createIterator([2,4,6])
    console.log(iterator.next())   // {done: false, value: 2}
    console.log(iterator.next())   // {done: false, value: 4}
    console.log(iterator.next())   // {done: false, value: 6}
    console.log(iterator.next())   // {done: true, value: undefined}
    

    2.生成器是一种返回迭代器的函数。
    \color{red}{注:} 不能用箭头函数来创建生成器。(1.标准规定;2.箭头函数是轻量级应用,类似单线程,不应增加包袱)

    function *createGenerator(arr) {
      for(let i=0; i<arr.length; i++) {
        yield arr[i]
      }
    }
    let generator = createGenerator([2,4,6])
    console.log(generator.next())   // {done: false, value: 2}
    console.log(generator.next())   // {done: false, value: 4}
    console.log(generator.next())   // {done: false, value: 6}
    console.log(generator.next())   // {done: true, value: undefined}
    

    3.迭代器的作用: 1.循环内部索引跟踪(迭代器 + for-of循环)

    // 不使用迭代器for循环
    let arr = [2,4,6]
    for(let i of arr) {
      console.log(arr[i])
    }
    // 1
    // 2
    // 3
    
    let arr = [2,4,6]
    let iterator = arr[Symbol.iterator]() // -> 可迭代的对象都具有Symbol.iterator属性
    console.log(iterator.next())   // {done: false, value: 2}
    console.log(iterator.next())   // {done: false, value: 4}
    console.log(iterator.next())   // {done: false, value: 6}
    console.log(iterator.next())   // {done: true, value: undefined}
    

    : 判断是否为可迭代对象** -> Symbol.iterator

    function isIterable(obj) {
      return typeof obj[Symbol.iterator] === 'function'
    }
    

    4.内建迭代器: ES6中为三种集合对象Array,Map和Set内置了三种迭代器。

    entries() -> 返回键值对
    values() -> 返回集合的值
    keys() -> 返回集合的键

    let arr = [1,2,3]
    for(let i of arr.entries()){
      console.log(i)
    }
    // [0,1]
    // [1,2]
    // [2,3]
    

    \color{red}{注:} 每一个集合类型都有一个默认的迭代器,在for-of中,如果没有显示指定则使用默认的迭代器。
    Array和Set集合的默认迭代器是values()方法;Map集合的默认迭代器是entries()方法。

    扩展 for-of (只支持Array,String,Map,Set;不支持Object)。
    \color{red}{注:} 对于数组,for-of只遍历数字类型的索引;for-in遍历所有属性。
    ->创建可迭代对象

    let obj = {
      arr: [2,4,6],
      *[Symbol.iterator]() {
        for(let i of this.arr) {
          yield i
        }
      }
    }
    for(let i of obj){
      console.log(i)
    }
    // 1
    // 2
    // 3
    

    5.高级迭代器功能: 1.给迭代器传递参数;2.生成器返回语句;3.委托生成器

    // 1.给迭代器传递参数
    function *createIterator() {
      let first = yield 1
      let second = yield first + 2
      yield second + 3
    }
    let itetator = createIterator()
    console.log(itetator.next()) // {done: false, value: 1}
    console.log(itetator.next(4)) // {done: false, value: 6} -> 为first赋值,返回first+2
    console.log(itetator.next(5)) // {done: false, value: 8} -> 为second赋值,返回second+3
    console.log(itetator.next()) // {done: true, value: undefined}
    
    // 2.生成器返回语句
    function *createIterator() {
      yield 1
      return 2
      yield 3
    }
    let itetator = createIterator()
    console.log(itetator.next()) // {done: false, value: 1}
    *!console.log(itetator.next()) // {done: true, value: 2}
    console.log(itetator.next()) // {done: true, value: undefined}
    
    // 3.委托生成器 - 合并迭代器
    function *createNumIterator() {
      yield 1
      yield 2
    }
    function *createColorIterator() {
      yield 'red'
      yield 'green'
    }
    function *createIterator() {
      yield *createNumIterator()
      yield *createColorIterator()
      yield true
    }
    let itetator = createIterator()
    console.log(itetator.next()) // {done: false, value: 1}
    console.log(itetator.next()) // {done: false, value: 2}
    console.log(itetator.next()) // {done: false, value: 'red'}
    console.log(itetator.next()) // {done: false, value: 'green'}
    console.log(itetator.next()) // {done: false, value: true}
    console.log(itetator.next()) // {done: true, value: undefined}
    
    // 4.委托生成器 - 迭代器间传值
    function *createNumIterator() {
      yield 1
      yield 2
      return 3
    }
    function *createRepeatIterator(count) {
      for(let i = 0; i < count; i++) {
        yield 'repeat,' + i
      }
    }
    function *createIterator() {
      let result = yield *createNumIterator()
      yield *createRepeatIterator(result)
    }
    let itetator = createIterator()
    console.log(itetator.next()) // {done: false, value: 1}
    console.log(itetator.next()) // {done: false, value: 2}
    console.log(itetator.next()) // {done: false, value: 'repeat, 0'} 注: 不打印3;需要yield result;return只有在最后一个迭代器中使用才能打印
    console.log(itetator.next()) // {done: false, value: 'repeat, 1'}
    console.log(itetator.next()) // {done: false, value: 'repeat, 2'}
    console.log(itetator.next()) // {done: false, value: undefined}
    

    6.异步任务执行

    // 1.向任务执行器传值
    function run(fn) {
      let task = fn() // 实例化生成器
      let result = task.next()
      function step() {
        if(!result.done) {
          result = task.next(result.value)
          step()
        }
      }
      step()
    }
    run(function *(){
      let value = yield 1
      console.log(value)   // 1 --> 先执行yield 1, 通过next(result.value), 将result.value-1传值给let value...
    
      value = yield value + 3
      console.log(value)   // 4
    })
    
    // 2.异步任务执行器
    function run(fn) {
      let task = fn() // 实例化生成器
      let result = task.next()
      function step() {
        if(!result.done) {
          if(typeof result.value === 'function') {
            setTimeout(() => {
              let data = result.value(1)
              result = task.next(data)
              step()
            }, 1000)
          } else {
            setTimeout(() => {
              result = task.next(result.value)
              step()
            }, 1000)
          }
        }
      }
      step()
    }
    function fn(val) {
      return val * 2
    }
    run(function *(){
      
      let value = yield fn
      console.log(value)   // 2 --> 先执行yield fn, 通过next(result.value), 将result.value-1传值给let value...
    
      value = yield value + 3
      console.log(value)   // 5
    })
    

    相关文章

      网友评论

          本文标题:第八章 迭代器Iterator和生成器Generator

          本文链接:https://www.haomeiwen.com/subject/ajazbltx.html