JavaScript中new Date().getTime()时间戳无法正确比较的问题排查
问题分析与解决方案
看起来你遇到的核心问题是类型不匹配导致的字符串拼接,咱们一步步拆解问题根源和解决办法:
问题根源
从你贴的日志能明显看出来:
currenttime是数字类型的时间戳(比如1616162621335)statusexpire却是字符串类型,而且数值异常大(比如"161616127040960000")
仔细看这个异常数值,其实是props.last_active的字符串值(比如"1616161270409")直接和60000(也就是1000*60)做了字符串拼接,而不是你预期的数值加法。这说明props.last_active从后端传到前端后,变成了字符串类型,而非数字类型。
解决方案
1. 修复类型转换,确保数值加法生效
首先要把props.last_active转换成数字类型后再计算过期时间,有几种常用方式:
- 使用
Number()强制转换:
const statusexpire = Number(props.last_active) + 1000 * 60;
- 用一元加号快速转换:
const statusexpire = (+props.last_active) + 1000 * 60;
- 或者用
parseInt(适合整数时间戳):
const statusexpire = parseInt(props.last_active, 10) + 1000 * 60;
2. 修复useEffect的逻辑缺陷
你当前的useEffect还有一个隐藏问题:currenttime是组件渲染时计算的固定值,不会实时更新,所以useEffect只会在组件挂载和props.id变化时执行一次,没法持续检查时间是否过期。
可以改成用定时器定时检查,同时监听props.last_active的变化:
useEffect(() => { // 封装检查逻辑成函数 const checkExpiration = () => { const currenttime = new Date().getTime(); const statusexpire = Number(props.last_active) + 1000 * 60; if (currenttime > statusexpire) { socket.emit('deletelogged', props.id); console.log('deleted' + props.id); } }; // 组件挂载时立即检查一次 checkExpiration(); // 每隔10秒检查一次(可以根据业务需求调整间隔) const intervalId = setInterval(checkExpiration, 10000); // 组件卸载时清理定时器,避免内存泄漏 return () => clearInterval(intervalId); }, [props.last_active, props.id]); // 依赖项加上props.last_active,确保它更新时重新计算
3. 后端层面的优化建议
如果可以的话,检查后端返回last_active字段的序列化逻辑,确保它以数字类型返回,而不是字符串。比如在MongoDB中new Date().getTime()本身是数字,但某些JSON序列化库可能会把大数字转成字符串,调整后端的返回配置可以从根源避免类型问题。
内容的提问来源于stack exchange,提问作者user15324999
相关产品推荐
相关产品推荐

