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

如何在Node.js中使用JSON文件存储倒计时剩余实时时长?

解决服务器重启后倒计时不重置的方案

核心思路

只存储初始时长无法恢复重启前的剩余进度,必须记录倒计时的截止时间戳。服务器重启后,通过当前时间与截止时间的差值计算剩余时长,就能还原之前的倒计时状态。

具体实现步骤

1. 修改存储文件结构

将原StartTime.json改为记录每个用户的初始时长(秒)和截止时间戳(毫秒),示例:

{
  "UserTime": [
    {
      "id": 1,
      "name": "Jack",
      "initialDuration": 1500, // 25分钟转秒:25*60=1500
      "deadline": 1720000000000 // 倒计时结束的毫秒时间戳
    },
    {
      "id": 2,
      "name": "Mike",
      "initialDuration": 1800, // 30分钟转秒:30*60=1800
      "deadline": 1720001000000
    }
  ]
}

注意:把时分格式的时长转成秒数,用Date.now()生成毫秒级时间戳,方便后续计算。

2. 服务器启动时恢复倒计时

读取存储的截止时间,计算当前剩余时长:

const fs = require('fs').promises;

async function loadUserTimers() {
  const data = await fs.readFile('./StartTime.json', 'utf8');
  const userTime = JSON.parse(data).UserTime;
  
  return userTime.map(user => {
    const now = Date.now();
    // 计算剩余秒数,确保不出现负数
    let remainingSeconds = Math.max(0, (user.deadline - now) / 1000);
    
    // 可选逻辑:如果倒计时已结束,自动重置为初始时长并更新截止时间
    if (remainingSeconds === 0) {
      remainingSeconds = user.initialDuration;
      user.deadline = now + remainingSeconds * 1000;
      await saveUserTimers(userTime);
    }
    
    return { ...user, remainingSeconds };
  });
}

async function saveUserTimers(userTime) {
  await fs.writeFile('./StartTime.json', JSON.stringify({ UserTime: userTime }, null, 2));
}

3. 实时更新并持久化状态

不要每秒写入文件(影响性能),建议在计时器状态变化(开始/暂停/结束)或定时(比如每分钟)更新截止时间:

async function updateUserDeadline(userId, newDeadline) {
  const data = await fs.readFile('./StartTime.json', 'utf8');
  const userTime = JSON.parse(data).UserTime;
  
  const userIndex = userTime.findIndex(u => u.id === userId);
  if (userIndex !== -1) {
    userTime[userIndex].deadline = newDeadline;
    await saveUserTimers(userTime);
  }
}

// 示例:每分钟批量更新一次文件
setInterval(async () => {
  // 这里可根据实际逻辑,更新正在运行的计时器截止时间
}, 60000);

4. 初始化新计时器逻辑

当用户首次创建计时器时,计算截止时间并写入文件:

async function createUserTimer(userId, name, initialMinutes) {
  const initialDuration = initialMinutes * 60;
  const deadline = Date.now() + initialDuration * 1000;
  
  const data = await fs.readFile('./StartTime.json', 'utf8');
  const userTime = JSON.parse(data).UserTime;
  
  userTime.push({ id: userId, name, initialDuration, deadline });
  await saveUserTimers(userTime);
}

额外注意事项

  • 错误处理:文件读写操作需包裹try/catch,避免程序因文件操作失败崩溃。
  • 时间精度:始终用毫秒级时间戳计算,不要依赖字符串格式的时间,避免解析误差。
  • 并发安全:如果有多个进程操作文件,建议用文件锁或改用轻量数据库(如SQLite)替代JSON文件,避免数据冲突。

内容的提问来源于stack exchange,提问作者maranR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 04:55:13