iT邦幫忙

2021 iThome 鐵人賽

DAY 15
1
Modern Web

追求JS小姊姊30天系列 第 15

追求JS小姊姊系列 Day15 -- 方函式的能力展現:認識生成器,工具人更神氣(下)

  • 分享至 

  • xImage
  •  

前情提要

生成器模式背後似乎有一個依循的規則

方函式:關於生成器運作的原理,其實跟工具人蠻像的
:又在拖台錢嗎


果然是個工具人,就該用工具人視角 來詮釋生成器原理吧

故事主要角色:

  1. 生成器:工具人
  2. 迭代器:以為能發展但其實是主僕的關係(老王新歌好聽
  3. 呼叫:知道他她喜歡你妳的你妳
  4. 回傳:回覆你她有男友了

故事開始:

(以下內容節錄於忍者2對於生成器執行原理的說明)

初始呼叫生成器這項動作,並不是真的執行它,而是建立一個迭代器,並透過迭代器來向生成器請求回傳(yield內容)。

翻譯: 最初妳會跟工具人互動,並不是真的想認識他,而是想建立可聯絡的關係,就能透過關係向工具人完成需求。

執行完後生成器狀態會轉為:暫停執行,等待下次的(next方法)再啟動,

翻譯: 當他處理完妳要他做的事情後,妳很自然的就不理他了,這時候他會耐心等待妳的下個需求


方函式:講到這裡,你是否有個疑問?如果按照工具人故事脈落推敲,所以生成器沒有終止的時候對嗎?

一般情境下答案是錯的

方函式:還記得第四個角色回傳嗎?當她決定回覆你的心意,告訴你她有男友時,就會終止了。
當然現實生活是不是這樣我不確定


認真的生成器執行原理:

現在,我們再重看一次,生成器的各個狀態:

  1. 待命中:當產生新的生成器就是這個狀態,此時並不會執行生成器的程式碼。

  2. 執行中:在此狀態下,會根據生成器內最初的/生成器最後暫停的位置繼續執行,==當對應的迭代器next呼叫時==,發現尚需執行的程式碼時,就會執行到下一個yield表達式。

  3. 暫停生產:當遇到yield表達式時,生成器會回傳一個物件,接著轉為暫停執行狀態,直到下次的next方法呼叫。

  4. 完成:當生成器處於執行中,執行到return,或是發現生成器所有yield內容都被執行時,就會進入完成狀態。

圖片引用來源:Secrets of the JavaScript Ninja, 2nd Edition.pdf

所以現實生活怎麼使用生成器 工具

  1. 規劃半天時程
    就算好幾個行程時間不確定,也一樣沒問題(下圖沒有加入時間因素)

沒有生成器的情境

function buyBreakfast(){
    console.log("早餐買好了"); 
    return function doTheLaundry(){
        console.log("衣服洗好了");
        return function walkTheDog(){
            console.log("遛好狗了");
            return function buyLunch(){
                console.log("午餐買好了")
            };
        };
    };
};

有生成器的情境
就算你時間上有不確定的因素(setTimeout),行程也能按照你預期的順序來執行。

//創造隨機時間的函式
function getRandomTime(x){
    return Math.floor(Math.random()*x)+1;
};
//參考:https://ithelp.ithome.com.tw/articles/10197904

function* planHalfOfDay(i){
    
    yield setTimeout(function buyBreakfast(){console.log("買好早餐"); },getRandomTime(5));
    yield setTimeout(function doTheLaundry(){console.log("洗好衣服!"); },getRandomTime(5));
    yield setTimeout(function walkTheDog(){console.log("遛狗好了!"); },getRandomTime(5));
    yield setTimeout(function buyLunch(){console.log("買好午餐"); },getRandomTime(5));
}

const control = planHalfOfDay();
control.next();

  1. 好工具就是要一直用 --- 如何讓生成器不終止

    方函式:捨不得工具人離開(終止)嗎?while建立一個永不停止的生成器,讓你一時用一時爽,一直用一直爽。

    :JS到底是怎樣的人啊..

function* keepToolManAliveForever(i){
    
    //充滿熱忱的初期
    yield "幫我做OX";
    yield "幫QQ";
    while(true){
        const keepHisAlive = yield "你是我特別的(工具)人";
        console.log(keepHisAlive);
        const doSomething = yield;
        console.log(doSomething);
    }
} 

let controlWay = keepToolManAliveForever();
controlWay.next();
  1. 任務分流 -- 重要的要先做
    方函式:工具人要做的事那麼多,如何博得她的眼光,就要懂得重要的先做,透過yield*,也能發現重要任務就先去執行
function* normalThing(i){
    
    
    yield "幫我做OX";
    yield "幫QQ";
    
    //先做重要的事情
    yield* moreImportantThing();
    yield "繼續做雜事吧";
} 

function* moreImportantThing(i){
    yield "先來接我啦";
}
let controlWay = normalThing();
controlWay.next();


結果是不是如你所想呢?

-- to be continued --


那今天就到這邊摟!今天分享喜歡的歌是:
Bruno Mars - The Lazy Song (Official Music Video)
https://www.youtube.com/watch?v=fLexgOxsZu0

每天的休息,是為了後面的追求,明天見。


reference:

忍者2
[JS] JavaScript Generator 的使用


上一篇
追求JS小姊姊系列 Day14 -- 方函式的能力展現:認識生成器,工具人更神氣(上)
下一篇
追求JS小姊姊系列 Day16 -- 方函式的能力展現:有小弟真好 -- 函式參數
系列文
追求JS小姊姊30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言