标签:回调函数 component 计时 count isp tst .com play ons
最近有一个需求是做一个闪购列表,列表中每一个商品都有倒计时,如果每一个倒计时都去生成一个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> ); } }
标签:回调函数 component 计时 count isp tst .com play ons
原文地址:https://www.cnblogs.com/minz/p/9346726.html