ES6基礎(chǔ)入門教程(十七)構(gòu)造器函數(shù)

調(diào)查:


阮一峰先生es6入門里面直接寫 Generator 函數(shù) ,一般人直接就懵了,這是什么?

我查詢了廖雪峰,阮一峰還有開課吧的相關(guān)資料以后,終于得出了一個比較靠譜的結(jié)論:
構(gòu)造器函數(shù)是一種,可以執(zhí)行到一部分就停止的函數(shù),每次調(diào)用,執(zhí)行其中的一部分。由
yield關(guān)鍵字控制每次調(diào)用的部分。

揭秘:


它能夠?qū)崿F(xiàn)一個什么目的呢?就是多個函數(shù)配合協(xié)同作戰(zhàn),第一個函數(shù),執(zhí)行到一半,交給第二個函數(shù),第二個執(zhí)行完了,再轉(zhuǎn)交給第一個函數(shù)繼續(xù)運行。用另一種方式實現(xiàn)了隊列概念。因為一般來說,單線程編程,函數(shù)從上而下執(zhí)行,是不能到一半中斷的,兩個函數(shù)配合就沒法完成了,但是有了構(gòu)造器函數(shù),一種行為變成了可能。
(但是你要注意的是,這個配合,仍然屬于單線程配合,如果想要實現(xiàn)多線程,可以使用worker。單線程協(xié)作,是一種折中的解決方案。)

先看簡單例子: 構(gòu)造器函數(shù)其實非常簡單,再function后面加一個*就行了:

function * fun(){
    yield 1+2 //第一次執(zhí)行返回
    yield 2+3 //第二次執(zhí)行返回
}
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}

由這個例子可以看出來,構(gòu)造器函數(shù)每次都返回一個對象,value是執(zhí)行語句后得到的值,done是執(zhí)行完畢沒有。

傳參:


但是我們最經(jīng)常遇到的情況應(yīng)該是下面這種:
需要把第一部分執(zhí)行完,得到的結(jié)果傳入后面的函數(shù),臥槽。那特么就十分的尷尬了。
請看這個函數(shù),尤其注意a,在函數(shù)的第二句中,a并不代表上面的let a,而是代表傳進來的

function * fun(){
    let a=yield 1+2 //第一次執(zhí)行返回
    let b=yield 1+3+a //第二次執(zhí)行返回
}
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:多個函數(shù)協(xié)程


我必須說,真是偉大的構(gòu)造器函數(shù),這一步充滿了想象力。
你必須從這個例子中才能感受到兩個函數(shù)配合的牛逼之處。
通過執(zhí)行到一部分內(nèi)容 突然用yield截斷后返回一個內(nèi)容,然后再通過判斷返回的內(nèi)容
決定用哪個函數(shù)繼續(xù)運行。

構(gòu)造器函數(shù)執(zhí)行結(jié)果
let houyi=function*(){
    console.log("開始準(zhǔn)備!我是houyi在執(zhí)行");
    yield "x"
    console.log("進入第四步!我是houyi在執(zhí)行");
    yield "s"
}
let xiahou=function*(){
    console.log("進入第二步,我是xiahou在執(zhí)行");
    yield "h"
    console.log("進入第三步!我是xiahou在執(zhí)行");
    yield "z"
}
let h=houyi();
let x=xiahou();
//流程控制
function run(gen){
    var v = gen.next();
    switch(v.value){
        // 發(fā)現(xiàn)是x運行x函數(shù)
        case "x":
        run(x);
        break;
        // 發(fā)現(xiàn)是h繼續(xù)運行x函數(shù)
        case "h":
        run(x);
        break;
        // 發(fā)現(xiàn)是z繼續(xù)運行x函數(shù)
        case "z":
        run(h);
        break;
    }
}
//開始執(zhí)行
run(h);

延申2:解決多個異步隊列


// 聲明3個異步函數(shù)
let fun1=()=>{
    setTimeout(()=>{
        console.log("第一步");
    },1000)
}


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


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

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

用構(gòu)造器函數(shù)解決多個異步函數(shù),
理論上異步隊列應(yīng)該用promise方式去處理,構(gòu)造器函數(shù)不是干這個用的,
但是復(fù)雜的情況誰也不好說,這方方式也應(yīng)該熟悉。

// 聲明3個異步函數(shù)
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)
}
// 創(chuàng)建順序構(gòu)造器函數(shù)
// 這里主要是利用了構(gòu)造器每次只能執(zhí)行一部分的原理
let shunxu=function*(){
    yield fun1;
    yield fun2;
    yield fun3;
}
// 執(zhí)行函數(shù) 把構(gòu)造器傳進來通過next運行即可
let run=(fn)=>{
    const go = fn();
    function yunxing(){
        const gofun = go.next();
        if(gofun.done) return; //.next返回done的值為ture時說明已經(jīng)結(jié)束 此時跳出函數(shù)
        // 這里容易讓人費解
        // 其實gofun表示的next()對象 它的value是當(dāng)前運行
        // 的那個函數(shù),此時再把yunxing函數(shù)傳進入執(zhí)行,其實跟回調(diào)也沒什么區(qū)別了
        gofun.value(yunxing)
    }
    yunxing();
}
run(shunxu);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在此處先列下本篇文章的主要內(nèi)容 簡介 next方法的參數(shù) for...of循環(huán) Generator.prototy...
    醉生夢死閱讀 1,488評論 3 8
  • 必備的理論基礎(chǔ) 1.操作系統(tǒng)作用: 隱藏丑陋復(fù)雜的硬件接口,提供良好的抽象接口。 管理調(diào)度進程,并將多個進程對硬件...
    drfung閱讀 3,763評論 0 5
  • 簡介 基本概念 Generator函數(shù)是ES6提供的一種異步編程解決方案,語法行為與傳統(tǒng)函數(shù)完全不同。本章詳細介紹...
    呼呼哥閱讀 1,136評論 0 4
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,666評論 1 32
  • layout: posttitle: 《Java并發(fā)編程的藝術(shù)》筆記categories: Javaexcerpt...
    xiaogmail閱讀 6,018評論 1 19

友情鏈接更多精彩內(nèi)容