摘要:可以利用這點做定時器的清理工作,而且可以說基本不會忘記可以將后面的變量可迭代的變量,字符串數組等中的值一個一個的返回。執行一次返回其中的一個值函數完美實現流程圖代碼部分其他變量下注下注階段完成后直接清除定時器。
扯蛋
做了兩年的Nodejs全棧開發,不知道為什么跑來做游戲呢(大概是廈門nodejs不好找工作吧)。用的是網易的pomelo的游戲框架。現接手了一個棋牌游戲:二十一點,不懂的規則的可以自行百度。
接手了平臺其他相關游戲的代碼,流程控制相互交錯,不易理解、難以維護。(可能是剛做游戲的原因,如果你們有什么更簡單的流程控制方法,歡迎分享)。我下意識的就想到了Generator函數的特性,感覺用著這里非常方便(以前一直覺得這是個異步流程控制中過度性質的方法,并且需要配合co才能自動執行,所以基本沒實際用過,koa不算...)
Js Generator函數實現流程控制的優點1、易于理解、便于開發、容易維護(看到Generator函數猶如看到了流程圖)
2、開發思路清晰(每個階段(函數)只需要關注自己的業務邏輯,完成直接下一步,而不用管下一步要做什么操作)
3、不存在會忘記清除定時器的問題
1、Generator函數執行后會生成一個Iterator。(注意不要加new)(簡單說就是個有next方法的對象,執行一次返回一個值)
2、每次next的調用,執行yield后面的語句并返回該語句執行的結果
3、每次只執行一個yield,后面的語句不會再執行、只有在執行下次next函數時才執行。(可以利用這點做定時器的清理工作,而且可以說基本不會忘記)
4、yield* 可以將后面的變量(可迭代的變量,字符串、數組等)中的值一個一個的返回。執行一次返回其中的一個值
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(); } } /** * 其他函數... */ }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99568.html
摘要:而在中是迭代器生成器,被創造性的拿來做異步流程控制了。當執行的時候,并不執行函數體,而是返回一個迭代器。行代碼再看看文章開頭的行代碼首先生成一個迭代器,然后執行一遍,得到的是一個對象,里面再執行。 廣告招人:阿里巴巴招前端,在這里你可以享受大公司的福利和技術體系,也有小團隊的挑戰和成長空間。聯系: qingguang.meiqg at alibaba-inc.com 首先請原諒我的標題...
摘要:以下展示它是如何工作的函數使用構造函數創建一個新的對象,并立即將其返回給調用者。在傳遞給構造函數的函數中,我們確保傳遞給,這是一個特殊的回調函數。 本系列文章為《Node.js Design Patterns Second Edition》的原文翻譯和讀書筆記,在GitHub連載更新,同步翻譯版鏈接。 歡迎關注我的專欄,之后的博文將在專欄同步: Encounter的掘金專欄 知乎專欄...
摘要:需要說明的是,每次執行完函數之后,都會返回一個對象這個返回值有兩個屬性和,對象通過這個返回值來告訴外界函數的執行情況。函數的返回值變成這樣可以發現的值變為了,因為函數已經執行完了。在規范中,新增了兩個協議可迭代協議和迭代器協議。 Koa是最近比較火的一款基于Node的web開發框架。說他是一個框架,其實他更像是一個函數庫,通過某種思想(或者說某種約定),將眾多的中間件聯系在一起,從而提...
摘要:換句話說,我們很好的對代碼的功能關注點進行了分離通過將使用消費值得地方函數中的邏輯和通過異步流程來獲取值迭代器的方法進行了有效的分離。但是現在我們通過來管理代碼的異步流程部分,我們解決了回調函數所帶來的反轉控制等問題。 本文翻譯自 Going Async With ES6 Generators 由于個人能力知識有限,翻譯過程中難免有紕漏和錯誤,還望指正Issue ES6 Gener...
摘要:關于協程和中的什么是協程進程和線程眾所周知,進程和線程都是一個時間段的描述,是工作時間段的描述,不過是顆粒大小不同,進程是資源分配的最小單位,線程是調度的最小單位。子程序就是協程的一種特例。 關于協程和 ES6 中的 Generator 什么是協程? 進程和線程 眾所周知,進程和線程都是一個時間段的描述,是CPU工作時間段的描述,不過是顆粒大小不同,進程是 CPU 資源分配的最小單位,...
閱讀 2582·2021-11-25 09:43
閱讀 1855·2021-09-22 15:26
閱讀 3723·2019-08-30 15:56
閱讀 1710·2019-08-30 15:55
閱讀 1892·2019-08-30 15:54
閱讀 810·2019-08-30 15:52
閱讀 3154·2019-08-29 16:23
閱讀 891·2019-08-29 12:43