大家都知道Promise是异步编程模型,它可以控制异步代码的执行。在ES6中新增了一个语法叫做Generator,它和Promise一样都可以用来处理异步操作。
Generator的原理
Generator 是一种特殊的函数,它可以被暂停和恢复执行。当一个 Generator 函数被调用时,它并不会立即执行,而是返回一个迭代器(Iterator)对象。每次调用迭代器的 next() 方法时,都会执行 Generator 函数的下一条语句,直到遇到 yield 关键字或函数结束为止。
在 Generator 函数中,yield 关键字用于指定暂停执行的位置,并可以向外部传递数据。当迭代器的 next() 方法被调用时,会从上一次暂停的位置继续执行,直到下一个 yield 关键字或函数结束为止。
Generator的使用
Generator的使用很简单,主要是是以下几点:
- 使用 * 来表示这是⼀个 Generator 函数
- 通过使用 yield 来暂停代码的执行
- 通过调用 next 来恢复代码的执行
function* generator() {
console.log('Start');
yield 1;
console.log('Middle');
yield 2;
console.log('End');
yield 3;
return 4;
}
let item = generator();
console.log(item.next()); // 输出 Star { value: 1, done: false }
console.log(item.next()); // 输出 Middle { value: 2, done: false }
console.log(item.next()); // 输出 End { value: 3, done: true }
console.log(item.next()); // 输出 { value: 4, done: true }
console.log(item.next()); // 输出 { value: undefined, done: true }
以这段代码为例,这里的generator可以是任何的名字,只要在function后加了*就代表这是一个Generator函数。
当12行代码执行时,此时Generator函数的代码会执行到第3行yield 1时停止,此时除了会打印函数里对'Star'的打印外,还会返回一个包含 value 和 done 两个属性的对象,value的值为Generator函数通过 yield 关键字产生的值 1,done的值为 false 表示 Generator 函数还未执行结束。
当执行到13行代码时,此时Generator函数的代码会执行到第5行yield 2时停止。value的值为Generator函数通过 yield 关键字产生的值 2,done的值为 false 表示 Generator 函数还未执行结束。
当执行到14行代码时,此时Generator函数的代码会执行到第7行yield 3时停止。value的值为Generator函数通过 yield 关键字产生的值 3,done的值为 true 表示 Generator 函数已经执行结束。
当执行到15行代码时,此时value的值为return的 4,done的值为 true。
当执行到16行代码时,此时value的值为undefined,done的值为 true。
for...of循环
for...of 循环是一种新的循环语法,它可以用来遍历可迭代对象中的元素。这个循环语法在 ES6 中被引入,支持遍历所有实现了迭代器协议的数据结构。
function* generator() {
console.log('Start');
yield 1;
console.log('Middle');
yield 2;
console.log('End');
yield 3;
}
let item = generator();
for (let a of item) { //输出'Star' '1' 'Middle' '2' 'End' '3'
console.log(a);
}
使用 for...of 循环遍历一个 Generator 函数生成的迭代器时,会依次获取 Generator 函数通过 yield 关键字产生的值。
Generator的作用
- 异步编程:Generator 函数能够简化异步编程,通过
yield关键字可以方便地暂停和恢复异步操作的执行流程。结合 Promise 或 async/await 可以更加优雅地处理异步操作。 - 无限序列:由于 Generator 函数是可以暂停和恢复执行的,因此可以用来表示无限的、懒计算的序列,从而节省内存空间和计算资源。
- 状态机:由于 Generator 函数的暂停和恢复特性,可以方便地实现状态机,简化复杂状态的管理和转换。
- 遍历器与可迭代对象:Generator 函数返回的迭代器对象具有遍历器的特性,可用于实现自定义的可迭代对象,并且可以通过
for...of循环进行遍历。 - 数据流处理:Generator 函数可以用于处理数据流,例如实现数据管道、数据筛选、数据转换等操作,使得代码更加清晰和易于维护。
总结
总的来说,Generator 函数通过其暂停和恢复执行的特性,为 JavaScript 提供了更加灵活和强大的编程能力,能够简化异步编程、处理无限序列、实现状态机等多种任务,使得代码更加简洁、易读和可维护。
最后假如您也和我一样,在准备春招。欢迎加微信shunwuyu ,这里有几十位一心去大厂的友友可以相互鼓励,分享信息,模拟面试,共读源码,齐刷算法,手撕面经。来吧,友友们!