Code前端首页关于Code前端联系我们

vue Generator函数的极少

terry 2年前 (2023-09-07) 阅读数 270 #Vue
文章标签 generator

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前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

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

热门