美文网首页
ES6 Iterator、Generator

ES6 Iterator、Generator

作者: 行走的蛋白质 | 来源:发表于2019-07-15 21:09 被阅读0次
  • Iterator 是什么,能做什么?
  • Generator 是什么,能做什么?


Iterator

Iterator 概念
  • iterator 是一种接口机制,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署了 iterator 接口就可以完成遍历操作
Iterator 作用
  • 为各种数据结构提供一个统一的简便的访问接口
  • 使得数据结构的成员能够按照某种次序排列
  • ES6 创造了一种新的遍历命令 for...of 循环,iterator 接口主要供 for...of 消费
Iterator 遍历过程
  • 创建一个指针对象,指向当前数据结构的起始位置。也就是说遍历器对象本质上就是一个指针对象
  • 第一次调用指针对象的 next 方法,可以将指针指向数据结构的第一个成员
  • 第二次调用指针对象的 next 方法,指针就指向数据结构的第二个成员
  • 不断调用指针对象的 next 方法,直到它指向数据结构的结束位置
简单实现 Array 的 Iterator 接口调用
let arr = ['a', 'b', 'c']
let iteratorFun = function(arr) {
    let nextIndex = 0
    return {
        next: function() {
            return nextIndex < arr.length ? {
                value: arr[nextIndex++],
                done: false
            } : {
                value: undefined,
                done: true
            }
        }
    }
}
let it = iteratorFun(arr)
console.log(it.next()) // {value: "a", done: false}
console.log(it.next()) // {value: "b", done: false}
console.log(it.next()) // {value: "c", done: false}
console.log(it.next()) // {value: undefined, done: true}
默认 Iterator 接口
  • ES6 规定,默认的 iterator 接口部署在数据结构的 Symbol.iterator 属性。也就是说一个数据结构只要有 Symbol.iterator 属性,就认为是可遍历的 iterable
  • Symbol.iterator 属性本身是一个函数,就是当前数据结构默认的遍历器生成函数,执行这个函数就会返回一个遍历器
let arr = ['a', 'b', 'c']
let it = arr[Symbol.iterator]()
console.log(it.next()) // {value: "a", done: false}
console.log(it.next()) // {value: "b", done: false}
console.log(it.next()) // {value: "c", done: false}
console.log(it.next()) // {value: undefined, done: true}

Generator

Generator 概念、作用
  • ES6 提供的解决异步编程的方案之一
  • Generator 是一个状态机,内部封装了不同状态的数据
  • 用来生成遍历器对象
  • 可暂停函数 ( 惰性求值 ),yield 可暂停,next 方法可启动,每次返回的是 yield 后的表达式结果
  • Generator 可以控制函数的执行,代替回调函数解决回调地狱问题
Generator 执行流程
function *fun1(x) {
    let y = 2 * (yield(x + 1))
    let z = yield(y / 3)
    return x + y + z
}
let doit = fun1(5)
console.log(doit.next()) // {value: 6, done: false}
console.log(doit.next(12)) // {value: 8, done: false}
console.log(doit.next(13)) // {value: 42, done: true}
  • 首先 Generator 函数调用和普通函数不同,它会返回一个迭代器
  • 当执行第一次 next 时,传参会被忽略,并且函数暂停在 yield (x + 1) 处,所以返回 5 + 1 = 6
  • 当执行第二次 next 时,传入的参数等于上一个 yield 的返回值,如果你不传参,yield 永远返回 undefined。此时 let y = 2 * 12,所以第二个 yield 等于 2 * 12 / 3 = 8
  • 当执行第三次 next 时,传入的参数会传递给 z,所以 z = 13, x = 5, y = 24,相加等于 42
Generator 用法实例
  • 用 Generator 生成器来达到 Promise 的效果,控制 ajax 工作流,代码有更好的可读性,从上到下,一气呵成。示例如下:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<script>

    function ajax(url) { // 创建 ajax 请求流程
        axios.get(url).then(res => userGen.next(res.data));
    }
    
    function* steps() { // 创建生成器函数
        console.log('ajax start users')
        const users = yield ajax('https://api.github.com/users');
        console.log(users, 'ajax start firstUser')
        const firstUser = yield ajax(`https://api.github.com/users/${users[0].login}`);
        console.log(firstUser, 'ajax start followers')
        const followers = yield ajax(firstUser.followers_url);
        console.log(followers, 'ajax end')
    }

    const userGen = steps(); 

    userGen.next(); // 流程开启

</script>

相关文章

网友评论

      本文标题:ES6 Iterator、Generator

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