秒杀需求的实现思路

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kellywong/article/details/82227005

首先大致说一下需求:大概就是要实现下面的效果,秒杀分为三个阶段: 预热中,抢购中,已结束。
预热中的展示效果又分为两种:当距离秒杀开始超过24小时的时候显示秒杀什么时候开始;当距离秒杀开始时间少于24小时的时候,开始倒计时。
抢购中的展示效果也分为两种:当距离秒杀结束超过24小时的时候显示秒杀什么时候结束;当距离秒杀结束时间少于24小时的时候,开始倒计时。
结束就展示已经结束。
这里写图片描述

基于imvc的实现:
1. 首先在control.js中我们通过从后台取得的活动开始时间effectTime,活动结束时间expireTime,以及当前服务器时间serviceDateTime,这三个时间来界定秒杀的状态seckillStatus(三种),当然还需要从接口获取当前产品是不是秒杀产品isSeckillProduct,然后吧=把effectTime,expireTime,seckillStatus,isSeckillProduct的值更新到state中。
2. 然后就是具体组件内部的渲染了,参考PC的SenKill.js组件,因为需要计时以及在24之内和之外的不同展示,这里组件内部state需要设计6个相关变量:

this.state = {
            currentHours: '',
            currentMinutes: '',
            currentSeconds: '',
            countTimer: null,  //计时器
            isShowPreheatTime: false, //控制预热中的两种展示
            isShowPurchaseTime: false, //控制抢购中的两种展示
        }

我们在render()中渲染代码,这里为了模块化,可以把秒杀模块在细化为一个子模块,然后就是根据上面state不同的值进行渲染了
3.所以重点是怎么控制这些状态,注意这里有关计时的,可以写在componentDidMount() 中,简单来说,就是接受父组件传来的秒杀开始,结束,状态信息,然后在预热中的时候,判断秒杀开始时间和当时时间(我觉得这里应该使用服务器时间)间隔,间隔大于24小时,不计时,只显示活动什么时候开始,间隔小于24小时,开始计时。同理,抢购中也是如此。

 componentDidMount() {
        const { seckillEffectTime, seckillExpireTime, seckillStatus } = this.props.state
        let countTimer = null
        let isShowPreheatTime = true
        let isShowPurchaseTime = true
        if (seckillStatus === '抢购中') {
            let difftime = formatTimeInterval(dateTimeConvert(new Date(), seckillExpireTime)
            if (parseInt(difftime.hours) > 24) {
                isShowPurchaseTime = false
            } else {
                countTimer = setInterval(() => this.countDown(seckillExpireTime), 1000)
            }
        }
        if (seckillStatus === '预热中') {
            let difftime = formatTimeInterval(seckillEffectTime, dateTimeConvert(new Date()))
            if (parseInt(difftime.hours) > 24) {
                isShowPreheatTime = false
            } else {
                countTimer = setInterval(() => this.countDown(seckillEffectTime), 1000)
            }
        }
        this.setState({
            isShowPreheatTime: isShowPreheatTime,
            isShowPurchaseTime: isShowPurchaseTime,
            countTimer: countTimer,
        })
    }

4.然后就是计时函数了,抢购中,如果从现在到结束时间间隔小于24小时,就需要一直计时,

countTimer = setInterval(() => this.countDown(seckillExpireTime), 1000)
countDown(time) {
    let countTime = formatTimeInterval(time, dateTimeConvert(new Date()))
    this.setState({
      currentHours: countTime.hours,
      currentMinutes: countTime.minutes,
      currentSeconds: countTime.seconds,
    })
  }

这里思考下conutTimer有问题没??看过之后发现缺少临界情况,当countTime=0的时候,是不是应该有所调整呢,当在预热期countTime=0那么就要进入抢购中,如果在抢购中,countTime=0,就要进入结束,所以需要增加临界情况:
一定要注意各种临界情况!!!!!

countDown(time) {
        const { countTimer } = this.state
        let { seckillEffectTime, seckillExpireTime, seckillStatus } = this.props.state
        const { handleChangeSeckillStatus } = this.props.handlers
        let countTime = formatTimeInterval(time, dateTimeConvert(new Date()))
        if (countTime.hours === '00' && countTime.minutes === '00' && countTime.seconds === '00') {
            clearInterval(countTimer)
            if (seckillStatus === '预热中') {
                handleChangeSeckillStatus('抢购中')
                let countTimer = null
                let isShowPreheatTime = true
                let isShowPurchaseTime = true
                let difftime = formatTimeInterval(new Date(), seckillExpireTime)
                if (parseInt(difftime.hours) > 24) {
                    isShowPurchaseTime = false
                } else {
                    countTimer = setInterval(() => this.countDown(seckillExpireTime, 1000)
                }
                this.setState({
                    isShowPreheatTime: isShowPreheatTime,
                    isShowPurchaseTime: isShowPurchaseTime,
                    countTimer: countTimer,
                })
            }
            if (seckillStatus === '抢购中') {
                handleChangeSeckillStatus('已结束')
            }
            return null
        } else {
            this.setState({
                currentHours: countTime.hours,
                currentMinutes: countTime.minutes,
                currentSeconds: countTime.seconds,
            })
        }
    }

5.最后完成时候,移除计时器

 componentWillUnmount() {
        clearInterval(this.state.countTimer)
    }

猜你喜欢

转载自blog.csdn.net/kellywong/article/details/82227005