使用Moment计算时间差实现基于时间戳的多阶段动作触发求助
实现方案
你的基础思路是正确的,基于diff方法计算时间差即可实现需求,优化方向主要是提升判断精度、增加状态锁避免重复触发,完整实现如下:
核心逻辑说明
基于毫秒级时间差做条件判断,三个动作的触发边界:
Prep:距离目标时间≤1小时,且未到目标时间Run:刚好到达/刚超过目标时间,且未到Reset触发节点Reset:超过目标时间≥15分钟
完整代码实现
const moment = require('moment'); // 浏览器端直接用全局moment即可 const targetTime = moment("2021-11-16T09:18:02+0000"); // 触发阈值(单位:毫秒,避免分钟级计算的精度误差) const PREP_THRESHOLD = 60 * 60 * 1000; // 1小时 const RESET_THRESHOLD = 15 * 60 * 1000; // 15分钟 // 状态锁,防止同一动作被重复触发 let hasRunPrep = false; let hasRunMain = false; let hasRunReset = false; function checkAndTrigger() { const now = moment(); // 差值为正代表还没到目标时间,为负代表已超过目标时间 const diffMs = targetTime.diff(now); // 触发Prep动作 if (diffMs <= PREP_THRESHOLD && diffMs > 0 && !hasRunPrep) { // 这里写你的Prep逻辑 console.log('执行Prep动作'); hasRunPrep = true; } // 触发Run动作 if (diffMs <= 0 && diffMs > -RESET_THRESHOLD && !hasRunMain) { // 这里写你的Run逻辑 console.log('执行Run动作'); hasRunMain = true; } // 触发Reset动作 if (diffMs <= -RESET_THRESHOLD && !hasRunReset) { // 这里写你的Reset逻辑 console.log('执行Reset动作'); hasRunReset = true; // 所有动作执行完成,清除定时器 clearInterval(timer); } } // 启动轮询,精度要求高可把1000(1秒)调小,比如100毫秒 const timer = setInterval(checkAndTrigger, 1000); // 浏览器端页面卸载时清理定时器,避免内存泄漏 window.addEventListener('beforeunload', () => clearInterval(timer)); // Node.js环境用如下清理逻辑 // process.on('exit', () => clearInterval(timer));
可选优化
如果后续要替换官方已停止维护的Moment.js,用API完全兼容的Day.js的话,上述代码不需要做任何逻辑修改,仅替换引入的库即可。
内容的提问来源于stack exchange,提问作者user13695382
相关产品推荐
相关产品推荐

