ES6基础入门教程(十七)构造器函数

调查:


阮一峰先生es6入门里面直接写 Generator 函数 ,一般人直接就懵了,这是什么?

我查询了廖雪峰,阮一峰还有开课吧的相关资料以后,终于得出了一个比较靠谱的结论:
构造器函数是一种,可以执行到一部分就停止的函数,每次调用,执行其中的一部分。由
yield关键字控制每次调用的部分。

揭秘:


它能够实现一个什么目的呢?就是多个函数配合协同作战,第一个函数,执行到一半,交给第二个函数,第二个执行完了,再转交给第一个函数继续运行。用另一种方式实现了队列概念。因为一般来说,单线程编程,函数从上而下执行,是不能到一半中断的,两个函数配合就没法完成了,但是有了构造器函数,一种行为变成了可能。
(但是你要注意的是,这个配合,仍然属于单线程配合,如果想要实现多线程,可以使用worker。单线程协作,是一种折中的解决方案。)

先看简单例子: 构造器函数其实非常简单,再function后面加一个*就行了:

function * fun(){
    yield 1+2 //第一次执行返回
    yield 2+3 //第二次执行返回
}
let g=fun()
console.log(g.next()); //{value: 3, done: false}
console.log(g.next()); //{value: 5, done: false}
console.log(g.next()); //{value: undefined, done: true}

由这个例子可以看出来,构造器函数每次都返回一个对象,value是执行语句后得到的值,done是执行完毕没有。

传参:


但是我们最经常遇到的情况应该是下面这种:
需要把第一部分执行完,得到的结果传入后面的函数,卧槽。那特么就十分的尴尬了。
请看这个函数,尤其注意a,在函数的第二句中,a并不代表上面的let a,而是代表传进来的

function * fun(){
    let a=yield 1+2 //第一次执行返回
    let b=yield 1+3+a //第二次执行返回
}
let g=fun();


let g1=g.next();
let g2=g.next(g1.value);
console.log(g1); //{value: 3, done: false}
console.log(g2); //{value: 7, done: false}

延申1:多个函数协程


我必须说,真是伟大的构造器函数,这一步充满了想象力。
你必须从这个例子中才能感受到两个函数配合的牛逼之处。
通过执行到一部分内容 突然用yield截断后返回一个内容,然后再通过判断返回的内容
决定用哪个函数继续运行。

构造器函数执行结果
let houyi=function*(){
    console.log("开始准备!我是houyi在执行");
    yield "x"
    console.log("进入第四步!我是houyi在执行");
    yield "s"
}
let xiahou=function*(){
    console.log("进入第二步,我是xiahou在执行");
    yield "h"
    console.log("进入第三步!我是xiahou在执行");
    yield "z"
}
let h=houyi();
let x=xiahou();
//流程控制
function run(gen){
    var v = gen.next();
    switch(v.value){
        // 发现是x运行x函数
        case "x":
        run(x);
        break;
        // 发现是h继续运行x函数
        case "h":
        run(x);
        break;
        // 发现是z继续运行x函数
        case "z":
        run(h);
        break;
    }
}
//开始执行
run(h);

延申2:解决多个异步队列


// 声明3个异步函数
let fun1=()=>{
    setTimeout(()=>{
        console.log("第一步");
    },1000)
}


let fun2=()=>{
    setTimeout(()=>{
        console.log("第二步");
    },800)
}


let fun3=()=>{
    setTimeout(()=>{
        console.log("第三步");
    },600)
}

fun1();
fun2();
fun3();

用构造器函数解决多个异步函数,
理论上异步队列应该用promise方式去处理,构造器函数不是干这个用的,
但是复杂的情况谁也不好说,这方方式也应该熟悉。

// 声明3个异步函数
let fun1=(sucess)=>{
    setTimeout(()=>{
        console.log("第一步");
        console.log(sucess);
        sucess();
    },1000)
}
let fun2=(sucess)=>{
    setTimeout(()=>{
        console.log("第二步");
        sucess();
    },800)
}
let fun3=(sucess)=>{
    setTimeout(()=>{
        console.log("第三步");
        sucess();
    },600)
}
// 创建顺序构造器函数
// 这里主要是利用了构造器每次只能执行一部分的原理
let shunxu=function*(){
    yield fun1;
    yield fun2;
    yield fun3;
}
// 执行函数 把构造器传进来通过next运行即可
let run=(fn)=>{
    const go = fn();
    function yunxing(){
        const gofun = go.next();
        if(gofun.done) return; //.next返回done的值为ture时说明已经结束 此时跳出函数
        // 这里容易让人费解
        // 其实gofun表示的next()对象 它的value是当前运行
        // 的那个函数,此时再把yunxing函数传进入执行,其实跟回调也没什么区别了
        gofun.value(yunxing)
    }
    yunxing();
}
run(shunxu);

Copyright © 2023 | 粤ICP备14006518号-4

Proudly powered by WordPress | Theme: Beast Blog by Crimson Themes.