如何让Node.js接口等待30秒超时,轮询验证支付状态
Node.js 下单接口支付验证的重试与超时实现
要解决“不无限等待、间隔重试、超时返回”的需求,核心是把异步查询逻辑改成Promise风格,再结合循环+定时器实现重试与超时控制,下面是具体的重构方案:
1. 重构支付验证函数(Service层)
把原来的callback写法改成返回Promise的async函数,这样更方便用async/await控制流程:
service.validateCustomerPayment = async function(amount, contact) { try { // 查询数据库中的支付记录 const paymentRecords = await Orders.find({ PhoneNumber: contact, flag: 'N' }); // 判断是否找到有效记录 if (paymentRecords?.length >= 1) { return 'record found'; } else { return 'record not found'; } } catch (dbError) { // 捕获数据库查询错误 throw new Error('some error occurred'); } };
2. 实现带重试和超时的下单接口(Controller层)
在下单接口里,通过循环检查耗时、间隔重试的方式,实现“找到记录立即返回,超时则返回超时响应”的逻辑:
controller.placeOrders = async function(req, res) { const { amount, contact } = req.body; const MAX_WAIT_TIME = 30000; // 最长等待30秒 const RETRY_INTERVAL = 1000; // 每隔1秒重试一次 const startTime = Date.now(); while (Date.now() - startTime < MAX_WAIT_TIME) { try { const validationResult = await service.validateCustomerPayment(amount, contact); // 找到支付记录,立即返回成功响应 if (validationResult.startsWith('record found')) { return res.status(200).json({ message: validationResult, code: 200 }); } // 没找到记录,等待指定间隔后重试 await new Promise(resolve => setTimeout(resolve, RETRY_INTERVAL)); } catch (error) { // 数据库查询出错,等待间隔后继续重试(也可根据需求直接返回错误) await new Promise(resolve => setTimeout(resolve, RETRY_INTERVAL)); } } // 超过30秒仍未找到记录,返回超时响应 res.status(408).json({ message: '支付验证超时,请稍后重试', code: 408 }); };
关键细节说明
- Promise化改造:抛弃callback风格,用async/await+Promise让异步流程更直观,避免回调嵌套
- 重试逻辑:用while循环判断已消耗时间,每次查询失败后等待固定间隔再重试
- 超时控制:通过记录起始时间,每次循环检查是否超过30秒,超时直接返回超时响应
- 错误处理:数据库查询出错时默认继续重试,你可以根据业务需求调整为直接返回错误响应
内容的提问来源于stack exchange,提问作者Denis Morgan
相关产品推荐
相关产品推荐

