1.迭代器 iterator
//1.是一个接口 快捷访问数据 Symbol.iterator创建迭代器 next()获取迭代的结果
//2.是用于遍历的指针(游标)
const items = ['one', 'two', 'three'];
//创建新的迭代器
const ite = items[Symbol.iterator]();
console.log(ite.next()); //{value: "one", done: false} done是否完成了遍历
console.log(ite.next()); //{value: "one", done: false} done是否完成了遍历
console.log(ite.next()); //{value: "one", done: false} done是否完成了遍历
console.log(ite.next()); //{value: undefined, done: true} done是否完成了遍历
2.生成器 generator函数
// generator函数 可以通过yield关键字,将函数挂起(让函数停留在当前位置),为改变执行流提供了可能性,为异步编程提供了方案
//generator函数 1.function后面 * 函数名前面 2.只能在函数内部使用yield表达式,让函数挂起
function* fn() {
console.log("start");
yield 1;
console.log("two");
yield 2;
console.log("end");
}
let yo = fn(); //调用generator函数时,不会立即执行,等待next
console.log(yo); //fn {<suspended>}
console.log(yo.next()); //start //{value: 1, done: false} 第一次next(),执行完第一个yield的内容。
console.log(yo.next()); //two //{value: 2, done: false}
console.log(yo.next()); //end //{value: undefined, done: true}
//generator函数 分段执行,调用next()开始执行,一直将一个yield之前和yield自身的内容执行完,若没有yield则全部执行。
yield详解
function* add() {
console.log('start');
let x = yield '1';
console.log('x:' + x);
let y = yield '2';
console.log('y:' + y);
return x + y;
}
let fn2 = add();
console.log(fn2.next(1));
//start
//{value: "1", done: false}
console.log(fn2.next(2));
//x:2
//{value: "2", done: false}
console.log(fn2.next(3));
//y:3
//{value: 5, done: true} 第二个next的参数赋给了x
console.log(fn2.next(4));
//{value: undefined, done: true}
生成器使用场景:为不具备iterator接口的对象提供遍历操作
function* fnIterator(obj) { //给obj对象生成迭代器
const props = Object.keys(obj);
for (const prop of props) {
yield [prop, obj[prop]]
}
}
const obj = {
name: 'hattie',
age: 18
}
obj[Symbol.iterator] = fnIterator;
for (const [k, v] of fnIterator(obj)) {
console.log(k + ':' + v);
}
Generator的应用 让异步代码同步化
function* load() {
loadUI();
yield showData();
hideUI();
}
const ite4 = load();
ite4.next();
test();
function test() {
console.log("函数按照调用顺序执行 setTimeout()相当于是异步的");
}
function loadUI() {
console.log('loading....');
}
function showData() {
setTimeout(() => {
console.log("数据加载完成");
ite4.next();
}, 1000);
}
function hideUI() {
console.log('load done');
}