Generator函数在流程控制中的应用

小编 2026-06-19 阅读:1142 评论:0
扯蛋 做了两年的Nodejs全栈开发,不知道为什么跑来做游戏呢(大概是厦门nodejs不好找工作吧)。用的是网易的pomelo的游戏框架。现接手了一个棋牌游戏:二十一点,不懂的规则的可以自行百...

扯蛋

做了两年的Nodejs全栈开发,不知道为什么跑来做游戏呢(大概是厦门nodejs不好找工作吧)。用的是网易的pomelo的游戏框架。现接手了一个棋牌游戏:二十一点,不懂的规则的可以自行百度。

\"在这里插入图片描述\"

二十一点游戏流程图

\"在这里插入图片描述\"

现状

接手了平台其他相关游戏的代码,流程控制相互交错,不易理解、难以维护。(可能是刚做游戏的原因,如果你们有什么更简单的流程控制方法,欢迎分享)。我下意识的就想到了Generator函数的特性,感觉用着这里非常方便(以前一直觉得这是个异步流程控制中过度性质的方法,并且需要配合co才能自动执行,所以基本没实际用过,koa不算...)

Js Generator函数实现流程控制的优点

1、易于理解、便于开发、容易维护(看到Generator函数犹如看到了流程图)
2、开发思路清晰(每个阶段(函数)只需要关注自己的业务逻辑,完成直接下一步,而不用管下一步要做什么操作)
3、不存在会忘记清除定时器的问题

简单说下Generator的执行流程

1、Generator函数执行后会生成一个Iterator。(注意不要加new)(简单说就是个有next方法的对象,执行一次返回一个值)
2、每次next的调用,执行yield后面的语句并返回该语句执行的结果
3、每次只执行一个yield,后面的语句不会再执行、只有在执行下次next函数时才执行。(可以利用这点做定时器的清理工作,而且可以说基本不会忘记)
4、yield* 可以将后面的变量(可迭代的变量,字符串、数组等)中的值一个一个的返回。执行一次返回其中的一个值

Js Generator函数完美实现流程图代码(部分)


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(); // 结算
    }

    *[\'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(); // 庄家操作
    }

    // 转到下个阶段
    nextStage() {
        process.nextTick(() => {
            this.flow.next();
        });
    }
    
    // 开始游戏
    start(seats) {
        /**
         * ...
         *
         */
        // 第一次next,直接进入下注阶段。整个流程走完游戏结束
        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了。只需要专注当前函数的功能,完成直接下一步
         */
        this.nextStage();
    }

    // 监听用户下注操作
    userBetOperateListener(uid){
    
        /**
         * ...
         * 检查是否在下注阶段,不是不能下注、记录每个玩家下注等
         */
         
        // 记录已下注的玩家
        this.betedPlayers[uid] = true;
        if (Object.keys(this.betedPlayers).length === this.seatCount) {
            // 如果所有玩家都押注完毕,
            this.nextStage();
        }
    }
    
    /**
     *  其他函数...
     */

}

来源:https://segmentfault.com/a/1190000017195986

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表