在Express网页游戏中,由另一HTTP请求resolve Promise的await模式可行吗?
这种异步等待式的游戏动作模式完全可行
你想要的这种用async/await替代回调的写法不仅能实现,还能让代码逻辑更清晰,避免回调嵌套的繁琐。核心是把game.ask()返回的Promise的resolve函数和玩家会话绑定暂存,让Express端点能找到并触发它。
具体实现思路
- 暂存resolve函数:让
game.ask()内部创建Promise时,把resolve函数存储起来(比如用内存Map或Redis,键用玩家ID),同时返回Promise让play()暂停等待。 - 前端交互触发:当玩家触发选择'Trees'的动作时,Express返回响应让前端显示选位置界面,此时
play()停在await处。 - 端点触发resolve:玩家选好位置后,前端请求对应的Express端点,端点根据玩家ID取出存储的
resolve函数,传入选中的hex值执行,play()就会继续执行后续的game.placeToken()逻辑。
代码示例
改造Game类,添加暂存逻辑
class Game { // 用Map存储玩家待处理的resolve函数,key为玩家ID private pendingResolves = new Map<string, (value: Hex) => void>(); ask<T>(prompt: SelectHex, playerId: string): Promise<T> { return new Promise((resolve) => { // 把resolve函数存入Map,绑定玩家ID this.pendingResolves.set(playerId, resolve); // 这里可以生成前端需要的交互提示信息 }); } // 供Express端点调用,完成resolve resolvePending(playerId: string, hex: Hex) { const resolve = this.pendingResolves.get(playerId); if (resolve) { resolve(hex); this.pendingResolves.delete(playerId); } } placeToken(hex: Hex, type: string) { // 你的放置逻辑 console.log(`Placed ${type} at ${hex}`); } } const game = new Game();
动作逻辑play()方法
async play(playerId: string): Promise<void> { const hex = await game.ask<Hex>(new SelectHex(), playerId); game.placeToken(hex, "greenery"); // 后续动作逻辑,比如通知玩家动作完成、更新游戏状态等 }
Express端点实现
const express = require('express'); const app = express(); app.use(express.json()); // 玩家触发选择Trees的端点 app.post('/play/trees', async (req, res) => { const { playerId } = req.body; // 启动play逻辑,无需等待完成(会被await暂停) game.play(playerId).catch(err => console.error('动作执行出错:', err)); // 返回响应,让前端显示选位置界面 res.json({ status: 'waiting_for_hex' }); }); // 玩家提交选中位置的端点 app.post('/select-hex', (req, res) => { const { playerId, hex } = req.body; game.resolvePending(playerId, hex); res.json({ status: 'action_done' }); }); app.listen(3000, () => console.log('服务器启动在3000端口'));
注意事项
- 内存泄漏问题:如果玩家长时间不操作,要定时清理Map中过期的resolve函数,避免内存占用过高。
- 分布式部署适配:如果是多服务器集群,内存Map无法共享,需要用Redis等分布式存储来替代。
- 错误处理:要捕获
play()中可能出现的Promise拒绝,避免未处理的Promise错误导致进程崩溃。
内容的提问来源于stack exchange,提问作者kberg
相关产品推荐
相关产品推荐

