深入理解ES6——迭代器(Iterator)和生成器(Generator)

深入理解ES6——迭代器(Iterator)和生成器(Generator)

文章目录

  • 深入理解ES6——迭代器(Iterator)和生成器(Generator)
    • 迭代器
    • 生成器
    • 生成器对象的方法
    • 可迭代对象和 `for-of` 循环
    • 访问默认迭代器
    • 创建可迭代对象
    • 内建迭代器
      • 集合对象迭代器
    • 字符串迭代器
    • NodeList迭代器
    • 高级迭代器的功能
      • 给迭代器传参
      • 在迭代器中抛出错误
      • 生成器返回语句
      • 委托生成器
    • 异步任务执行
      • 简单任务执行器
      • 向任务执行器传递数据
      • 异步任务执行器

生成器的出现旨在消除跟踪 for 遍历迭代变量 i 的复杂性并减少循环中的错误

迭代器

迭代器是一个特殊的对象,它具有一些专门为迭代过程设计的专有接口,所有迭代器都有一个 next() 方法,每次调用都放回一个结果对象。结果对象有两个属性:一个是 value 表示下一个将要返回的值;另一个是 done ,它是一个布尔类型的值,当前没有更多可返回数据是返回 true 。迭代器还会保存一个内部指针,用来指向当前集合中值的位置,每调用一次 next() 方法,都会返回下一个可用的值。

举例:

function createIterator(items) {
  var i = 0
  
  return {
    next: function() {
      var done = (i >= items.length)
      var value = !done ? items[i++] : undefined
      
      return {
        done: done,
        value: value
      }
    }
  }
}

var iterator = createIterator([1,2,3])

console.log(iterator.next())  
console.log(iterator.next())
console.log(iterator.next())
// 之后所有调用都会返回相同的内容
console.log(iterator.next())

生成器

生成器是一种返回迭代器的函数。 通过 function 关键字后面 加 * 来定义,使用 yield 关键字返回迭代器

不能用箭头函数来生成迭代器

举例:

function *createIterator() {
  yield 1;
  yield 2;
  yield 3;
}
// 生成器的调用方式和普通函数调用方式相同,只不过返回的是一个迭代器
let iterator = createIterator();

console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
console.log(iterator.next().value); // 3

生成器对象的方法

可以将生成器添加到对象中

可迭代对象和 for-of 循环

可迭代对象具有 Symbol.iterator 属性

for-of循环每执行一次都会调用可迭代对象的 next() 方法,并将迭代器返回的结果对象的 value 属性存储在一个变量中,循环将持续执行直到返回对象的 done 属性的值为 true

举例:

let values = [1,2,3];

for(let num of values) {
  console.log(num)
}
// 输出结果
// 1
// 2
// 3

访问默认迭代器

Symbol.iterator

创建可迭代对象

*[Symbol.iterator]() {}

内建迭代器

集合对象迭代器

  • entries()
  • values()
  • keys()

字符串迭代器

NodeList迭代器

NodesList 代码文档页面中所有元素的集合

高级迭代器的功能

给迭代器传参

通过 next(val) 传给下一个迭代器

在迭代器中抛出错误

生成器返回语句

function *createIterator() {
  yield 1;
  return; // 终止后面的执行
  yield 2;
}

委托生成器

异步任务执行

简单任务执行器

function run(taskDef) {
  // 创建一个无使用限制的迭代器
  let task = taskDef();
  
  // 开始执行任务
  let result = task.next();
  
  // 循环调用next()的函数
  function step() {
    if(!result.done) {
      result = task.next();
      step()
    }
  }
  // 开始迭代执行
  step();
}

向任务执行器传递数据

异步任务执行器

你可能感兴趣的:(JavaScript)