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

如何使Promise等待用户输入后执行,避免直接进入条件判断?

问题描述

我创建了一个存储用户选择项的数组,每个选择项包含用户ID和一个Promise,这个Promise本该在用户完成输入选择后运行filter函数。但实际运行时,程序没有等待用户输入就直接跳转到条件检查环节,导致此时没有用户选择内容,selection的长度始终小于1。请问需要补充什么逻辑才能让程序暂停并等待用户输入?

相关代码

function filter (x) {
        if (x.author.id === client.user.id) {
          return false;
        };

        var content = x.content.split(',').map(x => x.trim()).filter(function (value, index, self) {
          return self.indexOf(value) === index;
        });

        if (content.length !== actions.pick) {
          x.channel.send("Invalid number of unique suggestions.");
          return false;
        };

        if (verifyContent(content)) {
          x.channel.send("**Selection confirmed.**");
          return true;
        } else {
          return false;
        };

        function verifyContent (a) {

          for (var i = 0; i < a.length; i++) {

            var index = parseInt(a[i]);

            if (isNaN(index) || a[i] % 1 !== 0) {
              x.channel.send("Invalid.");
              return false;
            };

            if (game.getPlayer(x.author.id).cards[index - 1] === undefined) {
              x.channel.send("Card(s) selected contain an invalid range.");
              return false;
            };
          };

          return true;

        };

      };
      picks.push({id: game.players[i].id, promise: dmc.awaitMessages({filter, max: 1, time: 60*1000})});
    };
  };

  for (var i = 0; i < picks.length; i++) {
    var selection = await picks[i].promise[0]
    selection = selection !== undefined ? selection.content.split(',').map(x => x.trim()) : new Array();
    if (selection.length < 1) {
       channel.guild.members.cache.find(x => x.id === picks[i].id).user.send("I randomly picked 
       your response from your choice of white cards!");
  }

问题原因与解决方案

核心问题

  1. dmc.awaitMessages()返回的是一个Promise,它最终resolve的是Discord.js的MessageCollection(消息集合),而非普通数组,直接取promise[0]会拿到undefined。
  2. 没有正确等待Promise完成就执行后续判断,导致程序跳过等待用户输入的环节。

修复代码

1. 修正循环中的Promise等待逻辑

将处理选择的循环代码修改为:

for (var i = 0; i < picks.length; i++) {
  // 等待Promise完成,获取消息集合
  const msgCollection = await picks[i].promise;
  // 从集合中取出符合条件的第一条消息
  const selectedMsg = msgCollection.first();

  // 处理用户输入内容
  const selection = selectedMsg ? selectedMsg.content.split(',').map(x => x.trim()) : [];

  if (selection.length < 1) {
    channel.guild.members.cache.find(x => x.id === picks[i].id).user.send("我从你的白卡选项中随机帮你选了一个!");
  }
}

2. 优化filter函数(可选)

将原filter函数中的var替换为let/const避免作用域问题,同时优化提示文本为中文:

const filter = (x) => {
  if (x.author.id === client.user.id) return false;

  const content = x.content.split(',').map(item => item.trim()).filter((value, index, self) => self.indexOf(value) === index);

  if (content.length !== actions.pick) {
    x.channel.send("无效的唯一选项数量,请重新输入。");
    return false;
  }

  if (verifyContent(content)) {
    x.channel.send("**选择已确认。**");
    return true;
  } else {
    return false;
  }

  function verifyContent(a) {
    for (const item of a) {
      const index = parseInt(item);
      if (isNaN(index) || item % 1 !== 0) {
        x.channel.send("输入无效,请输入整数。");
        return false;
      }
      if (!game.getPlayer(x.author.id).cards[index - 1]) {
        x.channel.send("选择的卡牌超出有效范围。");
        return false;
      }
    }
    return true;
  }
};

3. 确保外层函数为async

使用await的代码必须处于async函数内部,如果你的外层函数还没声明为async,需要补充:

async function yourMainFunction() {
  // 你的原有代码,包括picks数组的创建、filter定义、循环等待逻辑
}

内容的提问来源于stack exchange,提问作者Peyton Sonnefeld

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:57:04