我使用了一些函数来获取日期和时间,然后将它们推送到DOM中的元素。它似乎工作得很好,直到几分钟后脚本消耗内存的铬并崩溃页面。以下是我认为会影响我的问题的代码:
'use strict';
// ///////////////////////////// INITIAL /////////////////////////////////// //
function leading_0( num ) {
if( num < 10 ) {
num = '0' + num;
}
return num;
}
// ////////////////////////////// DATES //////////////////////////////////// //
function getCurrentTime( date ) { // TIME / / / / / / / / / / / / / / / / / //
var hours = date.getHours(),
minutes = date.getMinutes(),
seconds = date.getSeconds(),
suffix = hours >= 12 ? 'PM' : 'AM',
fullTime;
hours = hours % 12;
if( hours === 0 ){
hours = 12;
}
minutes = leading_0( minutes );
seconds = leading_0( seconds );
fullTime = hours + ':' + minutes + ':' + seconds + ' ' + suffix;
return fullTime;
} // \\/ / / / / / / / / / / / / / / TIME / / / / / / / / / / / / / / / / / //
function getYear( date ) { /// / / / YEAR / / / / / / / / / / / / / / / / / //
var year = date.getFullYear();
return year;
} // \\/ / / / / / / / / / / / / / / YEAR / / / / / / / / / / / / / / / / / //
function getMonthDay( date ) { /// MONTH DAY / / / / / / / / / / / / / / / ///
var day = date.getDate();
return day;
} // \\/ / / / / / / / / / / / / / MONTH DAY / / / / / / / / / / / / / / / ///
function getMonth( date ) { // / / / MONTH / / / / / / / / / / / / / / / / ///
var months = [
'January', 'Feburary', 'March',
'April', 'May', 'June',
'July', 'August', 'September',
'October', 'November', 'December'
],
month = months[ date.getMonth() ];
return month;
} // \\/ / / / / / / / / / / / / / / MONTH / / / / / / / / / / / / / / / / ///
function getWkDay( date ) { /// / / WEEK DAY / / / / / / / / / / / / / / / ///
var weekdays = [
'Sunday', 'Monday',
'Tueday', 'Wednesday',
'Thursday', 'Friday',
'Saturday'
],
wkDay = weekdays[ date.getDay() ];
return wkDay;
} // \\ / / / / / / / / / / / / / / WEEK DAY / / / / / / / / / / / / / / / ///
function callBySec( func ) {
setInterval( func, 1000 );
}
function pushDate(){ /// / / / / / PUSH DATES / / / / / / / / / / / / / / / //
var today = new Date(),
wkDay,
month,
day,
year,
time,
d = document;
wkDay = getWkDay( today );
month = getMonth( today );
day = getMonthDay( today );
year = getYear( today );
time = getCurrentTime( today );
d.getElementById( 'wkDay' ).textContent = wkDay;
d.getElementById( 'month' ).textContent = month;
d.getElementById( 'day' ).textContent = day;
d.getElementById( 'year' ).textContent = year;
d.getElementById( 'time' ).textContent = time;
callBySec( pushDate );
} // \\/ / / / / / / / / / / / / / PUSH DATES / / / / / / / / / / / / / / / //
// ////////////////////////////// START //////////////////////////////////// //
function start() {
pushDate();
}
start();
<p>
<span id="wkDay"></span>,
<span id="month"></span> <span id="day"></span>,
<span id="year"></span> <b>|</b> <span id="time"></span>
</p>
上面的代码是一个主要的记忆猪吗?即使在这个SO页面上,它最终也会崩溃。有没有更好的方法来做到这一点并获得相同的结果?
答案 0 :(得分:2)
取出这一行:
callBySec( pushDate );
在pushDate()
的末尾。您已经使用setInterval()
每秒调用该功能,您不需要再次启动计时器。结果是您每秒都在创建另一个计时器。一分钟后,您每秒钟运行该功能60次。
如果callBySec
使用setTimeout()
而不是setInterval()
,您的代码将是正确的。
然后start()
函数应调用callBySec
:
'use strict';
function leading_0(num) {
if (num < 10) {
num = '0' + num;
}
return num;
}
function getCurrentTime(date) {
var hours = date.getHours(),
minutes = date.getMinutes(),
seconds = date.getSeconds(),
suffix = hours >= 12 ? 'PM' : 'AM',
fullTime;
hours = hours % 12;
if (hours === 0) {
hours = 12;
}
minutes = leading_0(minutes);
seconds = leading_0(seconds);
fullTime = hours + ':' + minutes + ':' + seconds + ' ' + suffix;
return fullTime;
}
function getYear(date) {
var year = date.getFullYear();
return year;
}
function getMonthDay(date) {
var day = date.getDate();
return day;
}
function getMonth(date) {
var months = [
'January', 'Feburary', 'March',
'April', 'May', 'June',
'July', 'August', 'September',
'October', 'November', 'December'
],
month = months[date.getMonth()];
return month;
}
function getWkDay(date) {
var weekdays = [
'Sunday', 'Monday',
'Tueday', 'Wednesday',
'Thursday', 'Friday',
'Saturday'
],
wkDay = weekdays[date.getDay()];
return wkDay;
}
function callBySec(func) {
setInterval(func, 1000);
}
function pushDate() {
var today = new Date(),
wkDay,
month,
day,
year,
time,
d = document;
wkDay = getWkDay(today);
month = getMonth(today);
day = getMonthDay(today);
year = getYear(today);
time = getCurrentTime(today);
d.getElementById('wkDay').textContent = wkDay;
d.getElementById('month').textContent = month;
d.getElementById('day').textContent = day;
d.getElementById('year').textContent = year;
d.getElementById('time').textContent = time;
}
function start() {
callBySec(pushDate);
}
start();
&#13;
<p>
<span id="wkDay"></span>,
<span id="month"></span> <span id="day"></span>,
<span id="year"></span> <b>|</b> <span id="time"></span>
</p>
&#13;
答案 1 :(得分:1)
尝试使用setTimeout()
而不是setInterval()
,因为后者会创建一个重复执行路径,而前者只是在未来的设定时间内运行一次代码块。
如果你拥有它,你每秒钟都会加倍pushDate()
的定期执行次数。
答案 2 :(得分:0)
我完全期望这是OOM,因为你正在使用递归,并且永远不会爆发。
问题是你最终得到了一个
的调用链pushDate -> callBySec -> pushDate -> callBySec -> PushDate -> etc
无穷。
你应该做的是完全摆脱callBySec
,并改变你的开始方法以使用setInterval
本身而不是依赖递归(你现在每秒都开始一个新的计时器)。 / p>
function start() {
setInterval(pushDate, 1000);
}
答案 3 :(得分:0)
setInterval()方法以指定的时间间隔(以毫秒为单位)调用函数或计算表达式。 setInterval()方法将继续调用函数,直到调用clearInterval()或窗口关闭。
取自https://www.w3schools.com/jsref/met_win_setinterval.asp
所以,基本上,你调用你的函数pushDate
,它启动一个定时器来每秒调用你的函数,每个被调用的函数都会启动另一个intervall。
如果你在start
函数中调用intervall而不是递归 - 那就没关系了。