美文网首页
遍历器与迭代器

遍历器与迭代器

作者: Mr无愧于心 | 来源:发表于2023-07-04 18:33 被阅读0次

    Iterator

    任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
    Iterator 的作用有三个:

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

    ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)

    Iterator 接口的目的,就是为所有数据结构,提供了一种统一的访问机制,即for...of循环

    let arr = ['a', 'b', 'c'];
    let iter = arr[Symbol.iterator]();
    
    iter.next() // { value: 'a', done: false }
    iter.next() // { value: 'b', done: false }
    iter.next() // { value: 'c', done: false }
    iter.next() // { value: undefined, done: true }
    
    

    生成一个Iterater

    function makeIterator(array) {
      var nextIndex = 0;
      return {
        next: function() {
          return nextIndex < array.length ?
            {value: array[nextIndex++]} :
            {done: true};
        }
      };
    }
    

    对于普通的对象object,for...of结构不能直接使用,会报错,必须部署了 Iterator 接口后才能使用,主要因为object是没有顺序的。如果想遍历的话,Object.keys方法将对象的键名生成一个数组,然后遍历这个数组

    for...of、for...in、forEach的区别
    • for...of
    1. 不能遍历对象
    2. 数据结构只要部署了Symbol.iterator属性,就被视为具有 iterator 接口,就可以用for...of循环遍历它的成员
    3. for...of循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、后文的 Generator 对象,以及字符串
    
    遍历键值键名的方式
    let arr = ['a', 'b', 'c'];
    for (let pair of arr.entries()) {
      console.log(pair);
    }
    // [0, 'a']
    // [1, 'b']
    // [2, 'c']
    
    
    • for...in
    1. 数组的键名是数字,但是for...in循环是以字符串作为键名“0”、“1”、“2”等等。
    2. for...in循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键。
    3. for...in循环会以任意顺序遍历键名,适合遍历对象,不适合遍历数组
    
    • forEach
    1. 无法中途跳出forEach循环,break命令或return命令都不能奏效
    

    Generater

    • Generator 函数是 ES6 提供的一种异步编程解决方案

    Generator 函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield表达式就是暂停标志。

    function* helloWorldGenerator() {
      yield 'hello';
      yield 'world';
      return 'ending';
    }
    var hw = helloWorldGenerator();// 返回一个遍历器对象 (Iterator Object)
    hw.next()
    // { value: 'hello', done: false }
    
    hw.next()
    // { value: 'world', done: false }
    
    hw.next()
    // { value: 'ending', done: true }
    
    hw.next()
    // { value: undefined, done: true }
    
    • yield 表达式

    每次遇到yield,函数暂停执行,下一次再从该位置继续向后执行(异步可中断,与react的机制相同,但是会引进新的副作用,所以没被react采用)。

    • 与 Iterator 接口的关系
      Generator 函数执行后,返回一个遍历器对象。该对象本身也具有Symbol.iterator属性,执行后返回自身。
    function* gen(){
      // some code
    }
    var g = gen();
    g[Symbol.iterator]() === g
    // true
    

    Generater的异步应用

    • 异步编程的方法
    1. 回调函数
    2. 事件监听
    3. 发布/订阅
    4. Promise 对象
    5. Generater
    6. async...await
    • 协程
      意思是多个线程互相协作,完成异步任务
    var fetch = require('node-fetch');
    function* gen(){
      var url = 'https://api.github.com/users/github';
      var result = yield fetch(url);
      console.log(result.bio);
    }
    
    var g = gen();
    var result = g.next();
    
    result.value.then(function(data){
      return data.json();
    }).then(function(data){
      g.next(data);
    });
    
    • Thunk 函数
      任何函数,只要参数有回调函数,就能写成 Thunk 函数的形式
    const Thunk = function(fn) {
      return function (...args) {
        return function (callback) {
          return fn.call(this, ...args, callback);
        }
      };
    };
    var readFileThunk = Thunk(fs.readFile);
    readFileThunk(fileA)(callback);
    

    基于 Thunk 函数的 Generator 执行器

    function run(fn) {
      var gen = fn();
    
      function next(err, data) {
        var result = gen.next(data);
        if (result.done) return;
        result.value(next);
      }
    
      next();
    }
    
    function* g() {
      // ...
    }
    
    run(g);
    

    CO模块自动执行

    function run(gen){
      var g = gen();
    
      function next(data){
        var result = g.next(data);
        if (result.done) return result.value;
        result.value.then(function(data){
          next(data);
        });
      }
    
      next();
    }
    
    run(gen);
    

    相关文章

      网友评论

          本文标题:遍历器与迭代器

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