You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何链式调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:05:18