关于迭代器的扩展

73 阅读2分钟

1. 关于迭代器的扩展

Iterator 是 ES6 引入的一种新的遍历机制

迭代机制

  • 通过 Symbol.iterator 创建一个迭代器,指向当前数据结构的起始位置

  • 随后通过 next 方法进行向下迭代指向下一个位置, next 方法会返回当前位置的对象,对象包含了 value 和 done 两个属性, value 是当前属性的值, done 用于判断是否遍历结束

  • 当 done 为 true 时则遍历结束

  let iterator = arr[Symbol.iterator](arr); //数组迭代器

  iterator.next(); //{value:1,done:false}

  iterator.next(); //{value:2,done:false}

  iterator.next(); //{value:undefined,done:true}

自己手写一个迭代器

//创建迭代器
function createIterator(item) {
  let i = 0;
  return {
    next() {
      let done = i >= item.length;
      let value = !done ? item[i++] : undefined;
      return {
        value,
        done,
      };
    },
  };
}
let arr = [22, 33, 44, 55];
let it = createIterator(arr);
console.log(it.next());//{value:22,done:false}
console.log(it.next());//{value:33,done:false}
console.log(it.next());//{value:44,done:false}
console.log(it.next());//{value:55,done:false}
console.log(it.next());//{value:undefined,done:true}

2. 生成器 generator

形式

function* gen() {
  yield 1;
  yield 2;
  yield 3;
}

通过生成器返回的是一个迭代器函数

let g = gen(); //这是一个迭代器
console.log(g.next()); //{value: 1, done: false}
console.log(g.next()); //{value: 2, done: false}
console.log(g.next()); //{value: 3, done: false}
console.log(g.next()); //{value: undefiend, done: true}javascript

3. 生成器 generator 的应用

  1. async/await 底层实现的机制就是基于生成器实现的
function API(num) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(num);
    }, 1000);
  });
}
//方案一:基于promise中的then处理
API(10)
  .then((data) => {
    return data + 10;
  })
  .then((data) => {
    console.log(data); //20
  });
//方案二:基于async/await处理
async function func() {
  let data = await API(10);
  data = await API(data + 10);
  console.log(data);
}
func();

//方案三
// 传递给我一个Generator函数,我可以把函数中的内容基于Iterator迭代器的特点一步步的执行
function asyncFunc(generator) {
  //创建一个迭代器函数,里面有方法next
  let iterator = generator();
  //创建next函数
  const next = (data) => {
    let { value, done } = iterator.next(data);
    if (done) return data;
    value.then((data) => {
      next(data);
    });
  };
  next();
}

asyncFunc(function* () {
  let data = yield API(100); //{value:API(100),done:false}
  data = yield API(data + 10); //{value:API(data + 10),done:false}
  console.log(data); //{value:undefined,done:true}
});