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>
最后编辑于 :2020.06.08 23:14:52
©著作权归作者所有,转载或内容合作请联系作者 【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。 平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。