成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Generator函數(shù)在流程控制中的應用

only_do / 1878人閱讀

摘要:可以利用這點做定時器的清理工作,而且可以說基本不會忘記可以將后面的變量可迭代的變量,字符串數(shù)組等中的值一個一個的返回。執(zhí)行一次返回其中的一個值函數(shù)完美實現(xiàn)流程圖代碼部分其他變量下注下注階段完成后直接清除定時器。

扯蛋

做了兩年的Nodejs全棧開發(fā),不知道為什么跑來做游戲呢(大概是廈門nodejs不好找工作吧)。用的是網(wǎng)易的pomelo的游戲框架。現(xiàn)接手了一個棋牌游戲:二十一點,不懂的規(guī)則的可以自行百度。

二十一點游戲流程圖

現(xiàn)狀

接手了平臺其他相關(guān)游戲的代碼,流程控制相互交錯,不易理解、難以維護。(可能是剛做游戲的原因,如果你們有什么更簡單的流程控制方法,歡迎分享)。我下意識的就想到了Generator函數(shù)的特性,感覺用著這里非常方便(以前一直覺得這是個異步流程控制中過度性質(zhì)的方法,并且需要配合co才能自動執(zhí)行,所以基本沒實際用過,koa不算...)

Js Generator函數(shù)實現(xiàn)流程控制的優(yōu)點

1、易于理解、便于開發(fā)、容易維護(看到Generator函數(shù)猶如看到了流程圖)
2、開發(fā)思路清晰(每個階段(函數(shù))只需要關(guān)注自己的業(yè)務邏輯,完成直接下一步,而不用管下一步要做什么操作)
3、不存在會忘記清除定時器的問題

簡單說下Generator的執(zhí)行流程

1、Generator函數(shù)執(zhí)行后會生成一個Iterator。(注意不要加new)(簡單說就是個有next方法的對象,執(zhí)行一次返回一個值)
2、每次next的調(diào)用,執(zhí)行yield后面的語句并返回該語句執(zhí)行的結(jié)果
3、每次只執(zhí)行一個yield,后面的語句不會再執(zhí)行、只有在執(zhí)行下次next函數(shù)時才執(zhí)行。(可以利用這點做定時器的清理工作,而且可以說基本不會忘記)
4、yield* 可以將后面的變量(可迭代的變量,字符串、數(shù)組等)中的值一個一個的返回。執(zhí)行一次返回其中的一個值

Js Generator函數(shù)完美實現(xiàn)流程圖代碼(部分)
class EsydProcess {

    constructor(room) {
        /**
         * ...其他變量
         */
        this.flow = this.flowGenerator();
    }

    *["flowGenerator"]() {

        yield this.betStage(); // 下注
        this.betStageTimer && clearTimeout(this.betStageTimer);// 下注階段完成后直接清除定時器。完全不用擔心定時器沒有被清理的情況

        yield this.assignStage(); // 分牌

        if (this.esydCard.getCardPoint(this.bankerCards[0]) === 1) {

            yield this.ensureStage(); // 保險
            this.ensureStageTimer && clearTimeout(this.ensureStageTimer);

            if (this.esydCard.getCardType(this.bankerCards) !== CardTypes.BLACK_JACK) {
                yield* this.operateStage(); // 操作
            }

        } else {
            yield* this.operateStage(); // 操作
        }

        yield this.settleStage(); // 結(jié)算
    }

    *["operateStage"]() {
        // 通知進入玩家操作階段
        this.noticeChangeStage(esydConsts.gameStage.OPERATE_STAGE);
        let players = this.players;
        for (let uid in players) {
            let player = players[uid];

            // 操作第一副牌
            yield this.changeOperatingPlayer(player);
            player.getCurCardInfo().isStop = true;
            this.operateTimer && clearTimeout(this.operateTimer);

            if (player.isSperated) {
                // 如果有一副牌,操作第二副牌
                player.curCardsIndex = 1;
                yield this.changeOperatingPlayer(player);
                player.getCurCardInfo().isStop = true;
                this.operateTimer && clearTimeout(this.operateTimer);
            }
        }
        yield this.bankerOperate(); // 莊家操作
    }

    // 轉(zhuǎn)到下個階段
    nextStage() {
        process.nextTick(() => {
            this.flow.next();
        });
    }
    
    // 開始游戲
    start(seats) {
        /**
         * ...
         *
         */
        // 第一次next,直接進入下注階段。整個流程走完游戲結(jié)束
        this.nextStage();
    }
    
    betStage(){
        // 進入下注階段
        this.noticeChangeStage(esydConsts.gameStage.BET_STAGE);
        /**
         * 其他操作
         */
        this.betStageTimer = setTimeout(() => {
            this.betStageTimer = null;
            // 超時,直接進入下一步。沒有下注的玩家使用默認底注
            this.nextStage();
        }, esydConsts.stageTime.BET_STAGE);
    }

    assignStage(){
        /**
         * ...
         * 分牌操作,完成直接下一步
         */
        this.nextStage();
    }

    ensureStage(){
        /**
         * ...
         * 各種操作,如通知客戶端、開始超時定時器等。操作完后直接下一步就Ok了。只需要專注當前函數(shù)的功能,完成直接下一步
         */
        this.nextStage();
    }

    // 監(jiān)聽用戶下注操作
    userBetOperateListener(uid){
    
        /**
         * ...
         * 檢查是否在下注階段,不是不能下注、記錄每個玩家下注等
         */
         
        // 記錄已下注的玩家
        this.betedPlayers[uid] = true;
        if (Object.keys(this.betedPlayers).length === this.seatCount) {
            // 如果所有玩家都押注完畢,
            this.nextStage();
        }
    }
    
    /**
     *  其他函數(shù)...
     */

}

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/99568.html

相關(guān)文章

  • 異步流程控制:7 行代碼學會 co 模塊

    摘要:而在中是迭代器生成器,被創(chuàng)造性的拿來做異步流程控制了。當執(zhí)行的時候,并不執(zhí)行函數(shù)體,而是返回一個迭代器。行代碼再看看文章開頭的行代碼首先生成一個迭代器,然后執(zhí)行一遍,得到的是一個對象,里面再執(zhí)行。 廣告招人:阿里巴巴招前端,在這里你可以享受大公司的福利和技術(shù)體系,也有小團隊的挑戰(zhàn)和成長空間。聯(lián)系: qingguang.meiqg at alibaba-inc.com 首先請原諒我的標題...

    tinna 評論0 收藏0
  • 《Node.js設(shè)計模式》基于ES2015+的回調(diào)控制

    摘要:以下展示它是如何工作的函數(shù)使用構(gòu)造函數(shù)創(chuàng)建一個新的對象,并立即將其返回給調(diào)用者。在傳遞給構(gòu)造函數(shù)的函數(shù)中,我們確保傳遞給,這是一個特殊的回調(diào)函數(shù)。 本系列文章為《Node.js Design Patterns Second Edition》的原文翻譯和讀書筆記,在GitHub連載更新,同步翻譯版鏈接。 歡迎關(guān)注我的專欄,之后的博文將在專欄同步: Encounter的掘金專欄 知乎專欄...

    LiuRhoRamen 評論0 收藏0
  • Generator開始學習Koa

    摘要:需要說明的是,每次執(zhí)行完函數(shù)之后,都會返回一個對象這個返回值有兩個屬性和,對象通過這個返回值來告訴外界函數(shù)的執(zhí)行情況。函數(shù)的返回值變成這樣可以發(fā)現(xiàn)的值變?yōu)榱耍驗楹瘮?shù)已經(jīng)執(zhí)行完了。在規(guī)范中,新增了兩個協(xié)議可迭代協(xié)議和迭代器協(xié)議。 Koa是最近比較火的一款基于Node的web開發(fā)框架。說他是一個框架,其實他更像是一個函數(shù)庫,通過某種思想(或者說某種約定),將眾多的中間件聯(lián)系在一起,從而提...

    doodlewind 評論0 收藏0
  • 通過ES6 Generator函數(shù)實現(xiàn)異步流程

    摘要:換句話說,我們很好的對代碼的功能關(guān)注點進行了分離通過將使用消費值得地方函數(shù)中的邏輯和通過異步流程來獲取值迭代器的方法進行了有效的分離。但是現(xiàn)在我們通過來管理代碼的異步流程部分,我們解決了回調(diào)函數(shù)所帶來的反轉(zhuǎn)控制等問題。 本文翻譯自 Going Async With ES6 Generators 由于個人能力知識有限,翻譯過程中難免有紕漏和錯誤,還望指正Issue ES6 Gener...

    劉厚水 評論0 收藏0
  • 關(guān)于協(xié)程和 ES6 中的 Generator

    摘要:關(guān)于協(xié)程和中的什么是協(xié)程進程和線程眾所周知,進程和線程都是一個時間段的描述,是工作時間段的描述,不過是顆粒大小不同,進程是資源分配的最小單位,線程是調(diào)度的最小單位。子程序就是協(xié)程的一種特例。 關(guān)于協(xié)程和 ES6 中的 Generator 什么是協(xié)程? 進程和線程 眾所周知,進程和線程都是一個時間段的描述,是CPU工作時間段的描述,不過是顆粒大小不同,進程是 CPU 資源分配的最小單位,...

    RyanHoo 評論0 收藏0

發(fā)表評論

0條評論

only_do

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<