当前位置: 首页 > 后端技术 > Node.js

生成器函数在过程控制中的应用

时间:2023-04-03 17:06:35 Node.js

废话。两年来,我一直在开发Nodejs全栈。不知道为什么要来这里做游戏(可能是因为厦门nodejs不好找工作)。使用的是网易的pomelo游戏框架。现在接手了一款桌游:二十一点,不懂规则的可以自行百度。二十一点游戏流程图的现状已经接管了平台上其他相关游戏的代码,流程控制交织在一起,难以理解和维护。(可能是刚做游戏的缘故,大家有什么更简单的流控方法,欢迎分享)。下意识的想到了Generator函数的特点,感觉用在这里很方便(之前一直觉得这是异步流程控制中的一个过度方法,需要配合co自动执行,所以我在实践中基本没用过,koa不算。。。)JsGenerator函数实现流程控制的优点1.易懂,易开发,易维护(看到Generator函数就像看到一张流程图)2.清晰的开发思路(每个阶段(功能)只需要关注自己的业务逻辑,直接完成下一步,不管下一步做什么)3.不存在忘记做的问题清除定时器(注意不要加new)(简单来说就是一个有next方法的对象,执行一次有返回值)2.每次调用next,执行yield之后的语句,结果是语句返回3.每次yield只执行一条,后面的语句不会再执行,下次执行next函数时才会执行。(可以用这个来清理定时器,可以说基本不会忘记)4.yield*可以返回以下变量(可迭代变量、字符串、数组等)中的值)一个接一个。执行一次并返回其中一个值。JsGenerator功能完美实现了流程图代码(部分)}*['flowGenerator'](){yieldthis.betStage();//Betthis.betStageTimer&&clearTimeout(this.betStageTimer);//下注阶段完成后直接清除计时器。不要担心计时器没有被清除yieldthis.assignStage();//分配卡片if(this.esydCard.getCardPoint(this.bankerCards[0])===1){yieldthis.ensureStage();//保险this.ensureStageTimer&&clearTimeout(this.ensureStageTimer);if(this.esydCard.getCardType(this.bankerCards)!==CardTypes.BLACK_JACK){yield*this.operateStage();//操作}}else{yield*this.operateStage();//操作}yieldthis.settleStage();//结算}*['operateStage'](){//通知玩家进入操作阶段this.noticeChangeStage(esydConsts.gameStage.OPERATE_STAGE);让玩家=this.players;for(letuidinplayers){letplayer=players[uid];//操作第一个牌组yieldthis.changeOperatingPlayer(player);player.getCurCardInfo().isStop=true;this.operateTimer&&clearTimeout(this.operateTimer);如果(玩家.isSperated){//如果有一副牌,则操作第二副牌player.curCardsIndex=1;yieldthis.changeOperatingPlayer(player);player.getCurCardInfo().isStop=true;this.operateTimer&&clearTimeout(this.operateTimer);}}yieldthis.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();}}/***其他函数...*/}