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
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。