如何链式调用MongoDB多个updateMany并等待响应?第三次更新延迟问题
问题根源
你遇到的两次刷新才生效的问题,本质是异步操作的时序混乱:
- 三个
updateMany是异步链式执行,但find查询是和第一个更新并行启动的——更新还没做完,查询就已经返回了旧数据,所以第一次刷新看不到第三个更新的效果。 - 第三个更新的查询条件依赖第一个更新刚写入的
todaysDateMs字段,哪怕链式then保证了顺序,但因为查询先完成,用户看到的还是未更新的状态,第二次刷新时所有更新才彻底完成。
修复代码
用async/await重构,让所有更新完成后再查数据,同时优化第三个更新的判断逻辑:
app.get('/', async (req, res) => { try { const todaysDate = new Date().toString().split(' ').slice(0, 4).join(' ') const todaysDateMs = new Date(`${todaysDate}, 00:00:00`).getTime() // 1. 给所有文档设置今日日期字段 await habitsCollection.updateMany({}, { $set: { todaysDate, todaysDateMs } }) // 2. 把未点击的文档标记为未完成 await habitsCollection.updateMany( { lastClicked: { $ne: todaysDate } }, { $set: { clicked: 'false' } } ) // 3. 重置超过48小时未点击的streak:直接用内存中的时间变量,不用依赖刚写入的字段 await habitsCollection.updateMany( { $expr: { $gte: [{ $subtract: [todaysDateMs, "$lastClickedMs"] }, 172800000] } }, { $set: { streak: 0 } } ) // 所有更新都做完了,再查最新数据返回页面 const results = await habitsCollection.find({}).toArray() const habitsLeft = results.filter(item => item.clicked === 'false').length res.render('index.ejs', { habits: results, dayVar: 'days', habitsLeft }) } catch (err) { console.error('操作出错:', err) res.status(500).send('服务器出错了') } })
核心优化说明
- 用
async/await替代嵌套then,让异步逻辑按顺序执行,确保所有更新完成后才查询数据,页面加载时就能拿到最新状态。 - 第三个更新直接用内存里的
todaysDateMs变量做计算,不用依赖刚写入文档的字段,避免MongoDB写操作的微小延迟导致判断不准。 - 加了
try/catch捕获错误,防止服务器崩溃,也方便调试。
内容的提问来源于stack exchange,提问作者Hannah
相关产品推荐
相关产品推荐

