为什么Canvas绘制逻辑在判断数据库返回值的if语句内不生效
问题原因
你遇到的是异步执行顺序问题:db.get() 是异步IO操作,返回Promise对象,你当前的代码没有等待数据库查询及后续的文本绘制逻辑执行完成,就提前执行了canvas.toBuffer()生成图片、发送消息,此时then回调里的文本绘制逻辑还未运行,所以生成的图片里永远不会出现目标文本。你去掉数据库判断后绘制逻辑变为同步执行,所以可以正常渲染。
修复方案
你可以选择以下任意一种方式调整代码执行顺序:
方案1:把图片生成、发送逻辑移到Promise回调内部
if(message.content.startsWith('#') && message.content.length == 7) { const canvas = Canvas.createCanvas(250, 250); const ctx = canvas.getContext('2d'); ctx.fillStyle = message.content; ctx.fillRect(0, 0, canvas.height, canvas.width) db.get("label"+message.author.id).then(value => { console.log(value) if(value == 'on') { console.log('true') ctx.font = '40px Poppins'; ctx.fillStyle = '#ffffff'; ctx.strokeStyle = '#000000' ctx.lineWidth = 1; ctx.fillText(message.content, canvas.width/10, canvas.height / 2 + 20); ctx.strokeText(message.content, canvas.width/10, canvas.height / 2 + 20); } // 所有绘制逻辑执行完成后再生成并发送图片 const attachment = new Discord.MessageAttachment(canvas.toBuffer(), 'color.png'); message.channel.send(attachment) }).catch(err => { // 可选:添加异常捕获处理数据库查询报错的场景 console.error('数据库查询失败', err) const attachment = new Discord.MessageAttachment(canvas.toBuffer(), 'color.png'); message.channel.send(attachment) }) }
方案2:用async/await改写(代码可读性更高)
需要先在外层包裹的函数上添加async修饰:
// 外层函数示例:async function messageHandler(message) { if(message.content.startsWith('#') && message.content.length == 7) { const canvas = Canvas.createCanvas(250, 250); const ctx = canvas.getContext('2d'); ctx.fillStyle = message.content; ctx.fillRect(0, 0, canvas.height, canvas.width) try { // 等待数据库查询完成 const value = await db.get("label"+message.author.id) console.log(value) if(value == 'on') { console.log('true') ctx.font = '40px Poppins'; ctx.fillStyle = '#ffffff'; ctx.strokeStyle = '#000000' ctx.lineWidth = 1; ctx.fillText(message.content, canvas.width/10, canvas.height / 2 + 20); ctx.strokeText(message.content, canvas.width/10, canvas.height / 2 + 20); } } catch (err) { console.error('数据库查询失败', err) } // 所有绘制逻辑执行完成后再生成并发送图片 const attachment = new Discord.MessageAttachment(canvas.toBuffer(), 'color.png'); message.channel.send(attachment) }
内容的提问来源于stack exchange,提问作者Harries
相关产品推荐
相关产品推荐

