我有一个函数,它返回两个日期时间之间的剩余时间,目前如果我刷新,我会得到该特定日期的当前时间。目前,如果我刷新,它只会返回正确的剩余时间,我尝试设置创建一个 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/