You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Express网页游戏中,由另一HTTP请求resolve Promise的await模式可行吗?

这种异步等待式的游戏动作模式完全可行

你想要的这种用async/await替代回调的写法不仅能实现,还能让代码逻辑更清晰,避免回调嵌套的繁琐。核心是把game.ask()返回的Promise的resolve函数和玩家会话绑定暂存,让Express端点能找到并触发它。

具体实现思路

  1. 暂存resolve函数:让game.ask()内部创建Promise时,把resolve函数存储起来(比如用内存Map或Redis,键用玩家ID),同时返回Promise让play()暂停等待。
  2. 前端交互触发:当玩家触发选择'Trees'的动作时,Express返回响应让前端显示选位置界面,此时play()停在await处。
  3. 端点触发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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 23:41:07