1. 迭代器
迭代器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator接口,就可以完成遍历操作
1.1 介绍
- ES6创造了一种新的遍历命令 for…of循环, Iterator接口主要供 for…of消费
- 原生具备 iterator接口的数据 (可用 for of遍历 )
a) Array
b) Arguments
c) Set
d) Map
e) String
f) TypedArray
g) NodeList
1.2 工作原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的
next
方法,指针自动指向数据结构的第一个成员 - 接下来不断调用
next
方法,指针一直往后移动,直到指向最后一个成员 - 每调用
next
方法返回一个包含value
和done
属性的对象
const xiyou = ['唐僧', '孙悟空', '猪八戒', '沙僧'];
let iterator = xiyou[Symbol.iterator]();
console.log(iterator.next()); // {value: "唐僧", done: false}
console.log(iterator.next()); // {value: "孙悟空", done: false}
console.log(iterator.next()); // {value: "猪八戒", done: false}
console.log(iterator.next()); // {value: "沙僧", done: false}
console.log(iterator.next()); // {value: undefined, done: true}
1.3 应用——自定义遍历数据
const banji = {
name: '终极一班',
stus: [
'xiaoming',
'xiaoning',
'xiaotian',
'knight'
],
[Symbol.iterator](){
let index = 0;
let _this = this;
return {
next:function(){
if(index < _this.stus.length){
const result = { value: _this.stus[index], done: false }
index++;
return result;
}else{
return {value: undefined, done: true}
}
}
};
}
}
for(let v of banji) {
console.log(v);
}
// 'xiaoming','xiaoning','xiaotian','knight'
2. 生成器
生成器函数是 ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同
2.1 声明与调用
*
的位置没有限制
function * gen(){
console.log('hello generator');
}
gen();
let iterator = gen();
console.log(iterator) // gen {<suspended>}
iterator.next(); // hello generator 【{value: undefined, done: true}】
函数代码分隔符 yield
- 生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到 yield 语句后的值
- yield 相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次 next 方法,执行一段代码
function * gen(){
yield '一只没有耳朵';
yield '一只没有尾巴';
return '真奇怪';
}
let iterator = gen();
console.log(iterator.next()); // {value: "一只没有耳朵", done: false}
console.log(iterator.next()); // {value: "一只没有尾巴", done: false}
console.log(iterator.next()); // {value: "真奇怪", done: true}
function * gen(){
console.log(111);
yield '一只没有耳朵';
console.log(222);
yield '一只没有尾巴';
console.log(333);
yield '真奇怪';
console.log(444);
}
let iterator = gen();
iterator.next(); // 111 【{value: "一只没有耳朵", done: false}】
iterator.next(); // 222 【{value: "一只没有尾巴", done: false}】
iterator.next(); // 333 【{value: "真奇怪", done: false}】
iterator.next(); // 444 【{value: undefined, done: true}】
传递实参
- next 方法可以传递实参,作为 yield 语句的返回值
function * gen(arg) {
console.log(arg);
const one = yield 111;
console.log(one);
const two = yield 222;
console.log(two);
const three = yield 333;
console.log(three);
}
let iterator = gen('AAA');
console.log(iterator.next()); // AAA {value: 111, done: false}
console.log(iterator.next('BBB')); // BBB {value: 222, done: false}
console.log(iterator.next('CCC')); // CCC {value: 333, done: false}
console.log(iterator.next('DDD')); // DDD {value: undefined, done: true}
生成器函数实例
异步编程实例,1s后控制台输出111,2s后输出222,3s后输出333
回调地狱
setTimeout(()=>{
console.log(111);
setTimeout(()=>{
console.log(222);
setTimeout(()=>{
console.log(333);
}, 3000);
}, 2000);
}, 1000);
生成器函数
function one() {
setTimeout(()=>{
console.log(111);
iterator.next();
}, 1000);
}
function two() {
setTimeout(()=>{
console.log(222);
iterator.next();
}, 2000);
}
function three() {
setTimeout(()=>{
console.log(333);
iterator.next();
}, 3000);
}
function * gen() {
yield one();
yield two();
yield three();
}
let iterator = gen();
iterator.next();