JavaScript 间隔函数来计算日期时间

标签 javascript momentjs setinterval

我有一个函数,它返回两个日期时间之间的剩余时间,目前如果我刷新,我会得到该特定日期的当前时间。目前,如果我刷新,它只会返回正确的剩余时间,我尝试设置创建一个 setinterval 函数,以便每隔几秒获取一次时间,但它不会每秒运行该函数。

到目前为止我的代码:

import moment from 'moment';

const calc = {

    vars: {
        interval: null,
        releaseDate: null,
        currentDate: null
    },

    elements: {
        releaseAt: document.getElementById('release-at'), // 2018-08-31 14:24:00
        currentDate: document.getElementById('current-date') // 2018-08-18 17:32:59
    },

    render () {
        moment().format();
        this.nextTick();
        this.vars.interval = setInterval(this.nextTick(), 1000);
    },

    nextTick () {
        let releaseDate = moment(this.elements.releaseAt.value);
        let currentDate = moment(this.elements.currentDate.value);

        if (currentDate.isBefore(releaseDate)) {
            currentDate.add(1, 'second');
            const diff = releaseDate.diff(currentDate);
            const diffDuration = moment.duration(diff);
            const difference = +releaseDate - +currentDate;

            return console.log(`
                ${diffDuration.months()} months
                ${diffDuration.days()} days
                ${diffDuration.hours()} hours
                ${diffDuration.minutes()} minutes
                ${diffDuration.seconds()} seconds left!`);
        } 

        console.log('boom! End ticker');

        return clearInterval(this.vars.interval);
    }

};

calc.render();

电流输出

            0 months
            12 days
            20 hours
            51 minutes
            0 seconds left!

最佳答案

让间隔发挥作用

你写的是:

setInterval(this.nextTick(), 1000); 

...当您可能是这个意思时:

setInterval(this.nextTick, 1000);  

在第一个示例中,this.nextTick()setInterval 之前进行评估,因此间隔尝试在 nextTick() 上工作。返回值而不是函数本身。如果 nextTick() 返回一个函数,这将很有用,但在这种情况下,它返回一个 clearInterval(),它没有返回值 - 所以你最终会运行 null 每秒一次。

在第二个示例中,函数本身就是将在时间间隔内运行的函数。这基本上是一种不太冗长的写作方式:

setInterval(function() { this.nextTick() }, 1000)

...但这在这里也不太适用,因为 nextTick() 依赖于保留相同的 this;在裸函数调用中,this 将恢复为 Window 对象,而不是您的 calc。使用粗箭头函数可以最轻松地保留 this:

setInterval(()=>{this.nextTick()}, 1000);

更新每个时间间隔的时间

同时,还有一个不相关的问题:您尝试使用 currentDate.add(1, 'second') 在每次更新时增加内部 currentDate 变量,但是从未在任何地方分配过该新值 - 并且每次都从(未修改的)输入字段重新填充该变量,这意味着您总是会得到相同的结果。相反,您可以将新值写入输入字段,该值将在下一个刻度时被拾取:

this.elements.currentDate.value = currentDate.add(1, 'second');

(或者,如果 currentDate 为空,您只能从表单字段中读取,否则仅依赖于内部变量。或者更好,因为您正在寻找的是当前时间,跳过表单字段内部变量,只使用Date()

一般来说,最安全的做法是依赖一个事实来源,而不是同时使用内部变量和 DOM 元素来保存相同的数据并保持它们同步。)

工作示例:

const calc = {

    vars: {
        interval: null,
        releaseDate: null,
        currentDate: null
    },

    elements: {
        releaseAt: document.getElementById('release-at'), // 2018-08-31 14:24:00
        currentDate: document.getElementById('current-date') // 2018-08-18 17:32:59
    },

    render () {
        moment().format();
        this.nextTick();
        this.vars.interval = setInterval(()=>{this.nextTick()}, 1000);
    },

    nextTick () {
        let releaseDate = moment(this.elements.releaseAt.value);
        let currentDate = moment(this.elements.currentDate.value);

        if (currentDate.isBefore(releaseDate)) {
            this.elements.currentDate.value = currentDate.add(1, 'second');
            const diff = releaseDate.diff(currentDate);
            const diffDuration = moment.duration(diff);
            const difference = +releaseDate - +currentDate;

            return console.log(`
                ${diffDuration.months()} months
                ${diffDuration.days()} days
                ${diffDuration.hours()} hours
                ${diffDuration.minutes()} minutes
                ${diffDuration.seconds()} seconds left!`);
        } 

        console.log('boom! End ticker');

        return clearInterval(this.vars.interval);
    }

};

calc.render();
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>

<input id="release-at" value="2018-08-31 14:24:00">
<input id="current-date" value="2018-08-18 17:32:59">

关于JavaScript 间隔函数来计算日期时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51912251/

相关文章:

javascript - 如何将小时添加到解析时刻日期?

javascript - Momentjs 我的格式有什么问题

javascript - 如何停止 "setInterval"

Node.js/Express 每月从 API 提取的流程

javascript - 在页面加载时加载 Twitter Bootstrap Popover

javascript - 如果图像尚未完全加载,插入加载器图标的最佳方法是什么?

javascript - 比较对象值并返回新数组

javascript - 三.js:如何将相同大小的对象放在屏幕顶部

javascript - bootstrap-datepicker:如何使用特定时区?

使用 setInterval 和触发器实现 jQuery 幻灯片平滑过渡