踩坑过程:业务需求实现倒计时组件,可以在后台管理系统实现装修,小程序正常展示,拿到需求后正常进行开发然后就给测试人员,结果就提了个bug:本地时间故意设置错误,导致倒计时不正确。
当时开发的时候没有想到这么多,直接拿Date.now()来倒计时了,结果就悲剧了~
解决方法:
思路:加载时和切换显示的时候获取服务器的时间,然后和本地时间也就是Date.now()或者New Date().getTime()进行对比,然后记录时间差也就是 timeGap = serverTime - Date.now(),然后在倒计时时间处理的时候加上时间差,也就是 nowTime = Date.now() + timeGap。
1.管理后台pc端的倒计时处理
getServerTime() {//获取服务器时间,其实和接口数据的请求头里面返回的那个时间一样
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
if (!xhr) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open("HEAD", location.href, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
resolve(xhr.getResponseHeader("Date"));
}
}
xhr.send(null);
})
}
...
// 监听页面隐藏和显示事件,避免第一次获取服务器时间后,中途修改了本地时间
document.addEventListener("visibilitychange", async function() {//注意兼容性
if (document.hidden) { //页面被切到后台-隐藏
clearInterval(Intervals);
} else { //页面被切到前台-显示
let serverTime = await getServerTime();
//倒计时只精确到秒
var timeGap = parseInt((new Date(serverTime).getTime() - Date.now()) / 1000);
}
});
...
//可以愉快地开始倒计时咯
var Intervals= setInterval(async () => {
let nowTime = parseInt(Date.now() / 1000) + that.countdown_timeGap; //当前时间
for (let i in data) {
//状态判断:未开始1,未结束2,已结束
...
}
}, 1000);
2.微信小程序端的倒计时处理
//在app.js的onshow事件里有个请求,用这个请求接口返回的请求头的时间来刷新我们的服务器时间
onShow: function (e) {
wx.request({
url: url,
method: method,
data: data,
header: {
'content-type': 'application/x-www-form-urlencoded'
},
success: function (res) {
//记录服务器时间差
this.serverTimeGap = parseInt(new Date(res.header.Date).getTime() - Date.now()) / 1000;
}
});
}
//可以愉快地开始倒计时咯
var Intervals= setInterval(async () => {
let nowTime = parseInt(Date.now() / 1000) + getApp().serverTimeGap; //当前时间
for (let i in data) {
//状态判断:未开始1,未结束2,已结束
...
}
}, 1000);
OK,以上~