如何使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!"); }
问题原因与解决方案
核心问题
dmc.awaitMessages()返回的是一个Promise,它最终resolve的是Discord.js的MessageCollection(消息集合),而非普通数组,直接取promise[0]会拿到undefined。- 没有正确等待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
相关产品推荐
相关产品推荐

