最近有一个需求是做一个闪购列表,列表中每一个商品都有倒计时,如果每一个倒计时都去生成一个setTimeout的话,一个页面就会有很多定时器,感觉这种做法不是非常好,于是换了一个思路。

思路是这样的,一个页面只生成一个定时器。页面利用对象去维护一个回调函数列表,key可以是id等唯一标识,value就是更新时间的函数,我这里用的是setState。提供一个往对象里添加回调函数的方法和一个移除回调函数的方法。

// 用于存放每个倒计时的回调方法
const countDownFuncList = {}; const addFunc = (key, func) => {
countDownFuncList[key] = func;
}
const removeFunc = (key) => {
delete countDownFuncList[key];
}

生成一个定时器,隔一定的时间就去遍历回调函数列表,调用里面的函数。

let intervalHandler = -1;
const countDown = () => {
if (intervalHandler !== -1) {
clearTimeout(intervalHandler);
}
intervalHandler = setTimeout(() => {
const now = new Date();
Object.keys(countDownFuncList).forEach((key) => {
const item = countDownFuncList[key];
if (typeof item === 'function') {
item(now);
}
})
}, 300);
}  

具体调用是调用timeContent方法来处理展示的时间。

const timeContent = (millisecond) => {
const second = millisecond / 1000;
let d = Math.floor(second / 86400);
let h = Math.floor((second % 86400) / 3600);
let m = Math.floor(((second % 86400) % 3600) / 60);
let s = Math.floor(((second % 86400) % 3600) % 60); let countDownDOM;
if (d > 0) {
countDownDOM = (<div class="count-down">{d} 天 {h} : {m} : {s}</div>);
} else {
countDownDOM = (<div class="count-down">{h} : {m} : {s}</div>);
} return countDownDOM;
}

这个方法有一个缺点就是当前时间的获取,除了初始化步骤以外,之后的更新都是通过new Date()来获取的,这样存在获取的时间可能并不是正确的当前时间的问题。

完整代码如下:

// 用于存放每个倒计时的回调方法
const countDownFuncList = {}; const addFunc = (key, func) => {
countDownFuncList[key] = func;
}
const removeFunc = (key) => {
delete countDownFuncList[key];
} const timeContent = (millisecond) => {
const second = millisecond / 1000;
let d = Math.floor(second / 86400);
let h = Math.floor((second % 86400) / 3600);
let m = Math.floor(((second % 86400) % 3600) / 60);
let s = Math.floor(((second % 86400) % 3600) % 60); let countDownDOM;
if (d > 0) {
countDownDOM = (<div class="count-down">{d} 天 {h} : {m} : {s}</div>);
} else {
countDownDOM = (<div class="count-down">{h} : {m} : {s}</div>);
} return countDownDOM;
} let intervalHandler = -1;
const countDown = () => {
if (intervalHandler !== -1) {
clearTimeout(intervalHandler);
}
intervalHandler = setTimeout(() => {
const now = new Date();
Object.keys(countDownFuncList).forEach((key) => {
const item = countDownFuncList[key];
if (typeof item === 'function') {
item(now);
}
})
}, 300);
} countDown(); class CountDownItem extends React.Component {
constructor(props) {
super(props);
this.state = {
currentTime: this.props.nowDate
} this.parseDisplayTime = this.parseDisplayTime.bind(this);
} componentDidMount() {
const { id } = this.props;
// 往事件列表添加回调函数
addFunc(id, this.updateTime);
} componentWillUnmount() {
const { id } = this.props;
// 从事件列表移除回调函数
removeFunc(id);
} updateTime(time) {
this.setState({
currentTime: time
})
} parseDisplayTime() {
const { endTime, id } = this.props;
const { currentTime } = this.state;
const subtractTime = endTime - currentTime;
let countDownDOM = '';
if(subtractTime > 1000){
countDownTimeDOM = (
<div className="count-down-content">
{timeContent(subtractTime)}
</div>
);
}else{
removeFunc(id);
} return countDownDOM;
} render(){
return(
<div className="count-down-wrap">{this.parseDisplayTime()}</div>
);
}
}

最新文章

  1. King&#39;s Quest —— POJ1904(ZOJ2470)Tarjan缩点
  2. 论垃圾邮件危害性及U-Mail邮件系统必杀技
  3. VPN连接失败
  4. 【转】使用Python的IDE:Eclipse+PyDev
  5. Delphi 实现Ini文件参数与TEdit和TCheckBox绑定(TSimpleParam)
  6. JavaBean-- 设置和取得属性
  7. 8.23.1 IO-输入输出流概念
  8. 如何进行系统配置 ——了解DOS下的内存
  9. 【XSY2708】hack 网络流
  10. 洛谷.3369.[模板]普通平衡树(fhq Treap)
  11. (整理)SQL Server 2008 CDC 功能使用
  12. Web 研发模式的演变
  13. sklearn datasets模块学习
  14. 在IIS7上部署aspx网站
  15. [转]【MyBatis】Decimal映射到实体类出现科学计数法问题
  16. HTML5 UI 控件Mobiscroll的使用(年月日三级联动)
  17. 牛客暑假多校第五场A.gpa
  18. Android系统Recovery工作原理之使用update.zip升级过程分析(一)---update.zip包的制作【转】
  19. 将php数组转js数组,js如何接收PHP数组,json的用法
  20. HTTP协议详解【转载】

热门文章

  1. double类型计算
  2. artDialog组件应用学习(三)
  3. Cannot execute request on any known server
  4. ZROJ#397. 【18提高7】模仿游戏(爆搜)
  5. 数据结构复习之C语言malloc()动态分配内存概述
  6. 【Linux】Linux 找回Root用户密码
  7. python进程与线程介绍
  8. 学习笔记-java 多线程
  9. 【Hibernate那点事儿】—— Hibernate应该了解的知识
  10. BZOJ1820:[JSOI2010]Express Service 快递服务(DP)