Discord.js的Embed组件中如何正确使用异步函数返回的Promise数据
问题根因
- 在Embed配置中直接调用异步方法时,拿到的是未完成的Promise对象,Discord序列化Embed内容时会将Promise转为默认字符串
[object Promise],无法展示实际业务值。 - 原有count.js存在逻辑缺陷:
fetchData异步方法没有显式返回值,依赖全局变量存储数据易引发时序错乱,也没有对外暴露可被外部await调用的异步接口。
正确实现方案
第一步:重构count.js的异步接口
将原有零散的异步逻辑封装为可直接返回结果的方法,避免全局变量带来的时序问题:
// count.js // 按实际业务定义初始值,避免未定义报错 let startingHour = 0; let startingMin = 0; // 对外导出可被await调用的count方法 export const count = async () => { // 复用原有业务判断逻辑 if (startingHour <= 0 && startingMin <= 0) { return 'Expired' } return `${startingHour} hours and ${startingMin} minutes` }
注:如果
startingHour、startingMin需要从外部接口拉取,直接在async方法内完成拉取、计算逻辑,最终return结果即可,无需依赖全局变量。
第二步:改造主消息逻辑
- 将
message事件的回调函数改为async,支持内部直接await异步方法 - 所有需要展示在Embed中的异步数据,必须先等待方法返回实际值,再写入Embed配置,禁止直接将异步方法调用结果作为配置项传入
修正后的主逻辑代码:
// 导入count方法 import { count } from './count.js' client.on('message', async (message) => { if (!message.content.startsWith(prefix) || message.author.bot) return; const args = message.content .slice(prefix.length) .trim() .split(/ +/); const command = args.shift().toLowerCase(); if (command === 'cd') { // 先等待异步方法返回实际业务值 let countValue = '数据加载失败'; try { countValue = await count(client); } catch (err) { console.log('数据获取异常:', err); } const cdEmbed = new Discord.MessageEmbed() .setColor('#0099ff') .setTitle('test') .setDescription('test embed') .addFields( // 用拿到的实际值填充字段,替换原有的硬编码0和直接调用的count(client) { name: '剩余冷却时间', value: countValue, inline: true }, ) .setTimestamp(); message.channel.send(cdEmbed); } });
避坑提醒
- 所有需要展示在Discord消息中的文本类内容,包括Embed的title、description、field的name/value、author信息等,都不能直接传入未await的Promise对象,必须等待异步结果返回后再填充。
- 异步方法调用时建议增加try/catch捕获逻辑异常,避免因数据获取失败导致整条消息无法发送。
内容的提问来源于stack exchange,提问作者Mod_ExtrEmE
相关产品推荐
相关产品推荐

