Node.js中Async/Await问题:MessageBird API消息发送异常排查
问题分析与解决方案
你说得对,**async/await的缺失(或者说异步逻辑处理不严谨)**确实可能是导致这个诡异现象的原因——虽然你的代码用了回调来处理异步操作,但嵌套的回调很容易出现隐性的错误遗漏、逻辑执行顺序偏差,甚至可能导致请求提前结束,让MessageBird的发送逻辑没有完全执行到位(尽管后台显示“已送达”,这可能是API返回的状态,但实际发送链路因为代码问题出了问题)。
先看看原代码的几个核心问题:
userInfo.find的回调嵌套过深,错误处理分散,一旦某个环节出错可能没有正确响应客户端,也难以排查- MessageBird的
messages.create用回调处理时,如果res.send之后还有未完成的逻辑,可能导致请求上下文被提前释放 - 缺少统一的错误捕获机制,有些错误可能直接被吞掉而没有输出
修改后的async/await版本代码
我们把所有异步操作改成async/await形式,同时统一错误处理,让逻辑更清晰:
const messagebird = require('messagebird')('ACCESS_KEY_API'); // 引入util来转换回调风格的方法为Promise形式 const util = require('util'); // 把MessageBird的create方法转换成Promise const createMessage = util.promisify(messagebird.messages.create); api.get('/sendmessage', async function (req, res) { try { // 先验证session有效性 if (!req.session.id) { return res.send("Unauthorized"); } const userid = req.session.user[0].id; // 用await等待用户查询完成,通过.exec()获取Promise对象 const user = await userInfo.find({ id: userid }).exec(); if (_.isEmpty(user)) { return res.send("No Results"); } const contact = user[0].contact; // 提前验证手机号码格式(MessageBird要求带国际国家码,比如+86xxxxxxxxx) if (!contact || !contact.startsWith('+')) { return res.send("Invalid phone number format"); } const params = { 'originator': 'MessageBird', 'recipients': [ contact ], 'body': 'Hello, world!' }; // 用await等待消息发送完成,确保逻辑顺序正确 const response = await createMessage(params); console.log(response); return res.send(response); } catch (err) { // 统一捕获所有错误,返回给客户端并打印详细日志 console.error("Error occurred:", err); return res.send("Error: " + err.message); } });
关键改动说明
- 路由函数改为async:允许我们在内部使用
await等待所有异步操作完成,彻底告别回调嵌套的“回调地狱” - Promise化异步方法:把
userInfo.find(通过.exec())和messagebird.messages.create(通过util.promisify)转换成Promise形式,让异步逻辑的执行顺序更直观 - 统一错误捕获:用
try/catch包裹所有业务逻辑,确保任何环节的错误都能被及时捕获、打印并反馈给客户端,避免错误被隐性吞掉 - 增加格式校验:提前检查手机号码格式,MessageBird要求号码必须带国际国家码,格式错误会导致消息无法实际送达,但API可能仍返回“已排队”状态
额外排查点
如果修改后还是有问题,可以检查这些地方:
- 确认你的
ACCESS_KEY_API是生产环境密钥,测试密钥发送的消息可能不会实际到达真实号码(虽然后台会显示状态) - 登录MessageBird后台查看消息的详细日志,看是否有“号码格式无效”“路由失败”等隐性错误
- 确认
user[0].contact确实是正确的、可接收短信的手机号码
内容的提问来源于stack exchange,提问作者NaturalCoder
相关产品推荐
相关产品推荐

