for循环中使用Async Await实现用户桌号分配功能运行异常求助
问题根因&修复方案
存在的BUG列表
- 接口未等待异步分配逻辑执行完成就返回响应:
asignTable是异步函数,路由中调用时未加await,导致数据库更新操作还没全部执行完接口就提前返回,更新时序混乱 - 分配循环逻辑错误:当前逻辑每轮先判断计数是否等于5,符合条件的情况下会直接跳过当前用户的分配,造成用户漏分配、桌号分布不规则
- 计数时序错误:
await Profile.findOneAndUpdate(filter, update).then(contador++)写法错误,contador++会同步立即执行,不会等待数据库更新完成,计数和实际更新进度错位,导致单桌人数不符合预期
修复后的代码
1. 路由接口修复(routes/index.js)
router.put('/asignTable', async (req, res) => { try { let users = await Profile.find() shuffle(users) await asignTable(users) // 新增await等待分配逻辑全部执行完成 const updatedUsers = await Profile.find() // 可选:查询最新数据返回给前端,保证返回的数据是更新后的 res.send(updatedUsers) } catch (err) { res.status(500).send({ message: '桌号分配失败', error: err }) } })
2. 分配逻辑修复(routes/utils.js)
async function asignTable(users) { let contador = 0 let numTable = 1 for (const user of users) { // 先判断当前桌是否满员,满员就切换下一桌 if (contador >= 5) { contador = 0 numTable++ } // 执行用户桌号更新,优先用_id查询避免同名用户更新错误 await Profile.findOneAndUpdate({ _id: user._id }, { table: numTable }) // 更新完成后再修改计数 contador++ console.log(`contador:${contador} numtable:${numTable} 用户名:${user.name}`) } }
优化建议
优先用_id作为查询条件更新用户数据,避免存在重名用户时误更新多条数据的问题,如果业务上要求name字段唯一,建议在Schema中给name字段加unique: true约束。
内容的提问来源于stack exchange,提问作者sebaanea
相关产品推荐
相关产品推荐

