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

使用discord.js开发Discord机器人异步与同步代码整合问题求助

问题根因
  • 你当前使用的forEach遍历为同步执行逻辑,不会等待内部异步Promise的then回调执行完成,就直接将未完成赋值的原始finalArgument推入结果数组,最终返回的数组自然都是未处理的原始参数值
  • 之前添加await报错是因为你将await写在了forEach的普通回调函数中,该回调没有被声明为async,不符合await的语法要求
解决方案

第一步:改造参数遍历逻辑

将原来的forEach遍历改为map遍历,为每个参数的处理返回Promise,再通过Promise.all等待所有参数处理完成。你已经将getCommandArgs声明为async函数,直接使用如下代码替换原有遍历逻辑即可:

// 用map生成Promise数组,每个迭代函数声明为async
const promiseList = argsList.map(async (argument, index) => {
    const type = args[index].type
    if (type === UserArgument) {
        // 直接await获取异步结果
        return await new UserArgument(argument).result
    } else if (type === MemberArgument) {
        return await new MemberArgument(argument, guild).result
    } else if (type === ChannelArgument) {
        return await new ChannelArgument(argument, guild).result
    } else if (type === RoleArgument) {
        return await new RoleArgument(argument, guild).result
    }
    // 不需要特殊处理的参数直接返回
    return argument
})
// 等待所有Promise执行完成,得到最终参数数组
const finalArgList = await Promise.all(promiseList)
return finalArgList

Promise.all会在任意一个Promise抛出错误时立即终止执行并抛出该错误,你可以在调用getCommandArgs的外层用try/catch统一捕获参数校验失败的异常,保证错误发生在命令执行之前。

第二步:调整调用侧逻辑

因为getCommandArgs是async函数,返回值为Promise,所以所有调用该函数的位置都需要添加await关键字,或者通过.then回调获取处理后的参数,否则会拿到Promise对象而非实际参数数组。

现有代码隐藏问题修复建议
  1. UserArgument构造函数的Promise逻辑存在无效执行问题:如果传入的是合法数字ID,users.fetch执行后没有终止代码,会继续调用#getUserFromName,虽然Promise状态只会变更一次,但会产生无效请求,建议在if (isNumeric(user))分支的fetch调用前添加return。
  2. #getUserFromName方法中遍历用户缓存的写法错误:for...in遍历Map得到的是键,你需要用for (const [userId, user] of ArgumentBase.client.users.cache)才能拿到用户对象,否则当前逻辑永远找不到匹配用户名的用户。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 18:27:00