1。调用generator函数
generator 函数几乎是一种全新的函数类型,它与标准的普通函数完全不同。
generator函数能生成一组值的序列,但每个值的生成是基于每次请求 与标准函数不同,它不会立即生成。
//定义一个generator函数
function* WeaponGenerator(){
yield "Katana";
yield "Wakizashi";
yield "Kusarigama";
}
//调用生成器得到一个迭代器
const weaponsIterator = WeaponGenerator();
//手动依次调用.next方法
//每次调用迭代器的next方法向生成器请求一个新值
weaponsIterator.next();//{ value: 'Katana', done: false }
weaponsIterator.next();//{ value: 'Wakizashi', done: false }
weaponsIterator.next();//{ value: 'Kusarigama', done: false }
weaponsIterator.next();//{ value: undefined, done: true }
//使用for-of循环
for (let item of WeaponGenerator()) {
console.log(item);//Katana、Wakizashi、Kusarigama
}2。与generator交互(传递参数)
function* WeaponGenerator(action){
const imposter = yield action;//imposter为下次调用next传递的参
yield imposter + " - " + action;
}
const weaponsIterator = WeaponGenerator("Sk");
weaponsIterator.next().value;//"Sk"
//第二次调用next中传递的参数,作为内部上一次调用yield的返回值
weaponsIterator.next("Hn").value;//"Hn - Sk"3。抛出异常
除了后续方法之外,每个迭代器还有一个抛出方法
function* WeaponGenerator(){
try{
yield "Hattori";
}
catch(e){
return e == "catch this";
}
}
const ninjaIterator = WeaponGenerator();
ninjaIterator.next()//{value: "Hattori", done: false}
ninjaIterator.throw("catch this")//{value: true, done: true}4。内部结构(实现原理)
挂起启动:generator创建后,首先在此状态下启动。里面没有代码被执行过。
执行:generator中代码的执行状态。执行刚刚开始或从上次暂停的位置继续执行。当generator对应的迭代器调用next方法并且当前有可执行代码时,generator将转换到该状态。
暂停Yield:当generator在执行过程中遇到yield表达式时,它会创建一个包含返回值的新对象,然后暂停执行。generator在此状态下暂停并等待继续执行。
完成:generator执行过程中,如果根据return语句执行代码或者执行全局代码,则generator进入该状态
generator功能
function* WeaponGenerator(){
yield "Hattori";
yield "Yoshi";
}代码执行流程
//1、创建generator,处于挂起状态
const ninjaIterator = WeaponGenerator();
//2、激活generator,从挂起状态转为执行状态。执行到 yield "Hattori" 语句终止
//进而转为挂起状态,返回新对象 {value: "Hattori", done: false}
const result1 = ninjaIterator.next();
//3、重新激活生成器,从挂起状态转为执行状态。执行到 yield "Yoshi" 语句终止
//进而转为挂起状态,返回新对象 {value: "Yoshi", done: false}
const result2 = ninjaIterator.next();
//4、重新激活生成器,从挂起状态转为执行状态。
//没有代码可执行,转为完成状态,返回新对象{value: false, done: true}
const result3 = ninjaIterator.next();通过执行上下文跟踪生成器函数
1。调用ninjaIterator之前:执行栈指向->全局执行上下文
ninjaIterator:函数
结果1:未定义
结果2:未定义
结果3:未定义
2。调用ninjaIterator函数:执行栈指向->WeaponGenerator
创建一个新的 ninjaIterator 对象,指向当前生成器上下文
创建一个新的堆栈元素并将其推入堆栈(WeaponGenerator)
此时函数不执行任何代码,而是返回一个新的迭代器;程序运行后,WeaponGenerator出现,但没有被销毁(由于ninjaIterator的引用)
WeaponGenerator执行上下文暂时挂起
执行栈再次引用全局执行上下文
3。调用ninjaIterator.next()方法:执行栈指向->WeaponGenerator生成器
重新激活相应的上下文并将WeaponGenerator推入堆栈
执行完毕后,再次挂起WeaponGenerator执行上下文
执行栈再次引用全局执行上下文
4。调用ninjaIterator.next()方法:重复上一步
5。执行完成,最终状态
5。迭代
6。一波源码分析
function createIterator(items) {
var i = 0
return {
next: function () {
var done = (i >= items.length)
var value = !done ? items[i++] : undefined
return {
done: done,
value: value
}
}
[Symbol.iterator]: function () {
return this
}
}
}
var iterator = createIterator([1, 2, 3])
...iterator // 1, 2, 3
code前端网




发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。