discord.js中如何正确获取多条连续发送消息的ID
问题原因
message.channel.send() 是异步方法,调用后会立刻返回Promise,不会等待消息实际发送完成就会执行下一行代码,3条消息的发送请求属于并行触发,响应顺序不受调用顺序控制。如果你的player变量是在循环中用var声明(无块级作用域),回调闭包捕获的变量会在执行时被覆盖,就会出现多个字段都被赋值为最后返回的第三条消息ID的问题。
修复方案
方案1:async/await串行发送(稳妥,可保证消息发送顺序和ID对应关系完全符合预期)
将代码放在带async标识的函数中,按顺序等待每条消息发送完成后再发送下一条:
// 外层函数需要添加async关键字,示例:async function handleMsg() { ... } const msg1 = await message.channel.send(`${acc[player].output.slot1}`) acc[player].ids.msg1 = msg1.id const msg2 = await message.channel.send(`${acc[player].output.slot2}`) acc[player].ids.msg2 = msg2.id const msg3 = await message.channel.send(`${acc[player].output.slot3}`) acc[player].ids.msg3 = msg3.id
方案2:Promise.all批量处理(适合不需要严格保证消息发送顺序的场景)
Promise.all返回的结果顺序和传入的Promise顺序完全一致,不受实际响应顺序影响:
Promise.all([ message.channel.send(`${acc[player].output.slot1}`), message.channel.send(`${acc[player].output.slot2}`), message.channel.send(`${acc[player].output.slot3}`) ]).then(([msg1, msg2, msg3]) => { acc[player].ids.msg1 = msg1.id acc[player].ids.msg2 = msg2.id acc[player].ids.msg3 = msg3.id })
如果player变量来自循环遍历逻辑,额外注意将var player = 遍历项修改为let player = 遍历项,利用let的块级作用域特性保证每个回调捕获的变量值正确。
内容的提问来源于stack exchange,提问作者Ray
相关产品推荐
相关产品推荐

