답변:
이는 지연을 저장하기 위해 32 비트 정수를 사용하는 setTimeout 때문이므로 허용되는 최대 값은
2147483647
시도하면
2147483648
문제가 발생합니다.
나는 이것이 JS 엔진에서 어떤 형태의 내부 예외를 일으키고 함수가 전혀 발생하지 않고 즉시 실행되도록 가정 할 수 있습니다.
49999861776383
( 49999861776384
콜백이 즉시 실행되도록 함)
49999861776383 % 2147483648 === 2147483647
당신이 사용할 수있는:
function runAtDate(date, func) {
var now = (new Date()).getTime();
var then = date.getTime();
var diff = Math.max((then - now), 0);
if (diff > 0x7FFFFFFF) //setTimeout limit is MAX_INT32=(2^31-1)
setTimeout(function() {runAtDate(date, func);}, 0x7FFFFFFF);
else
setTimeout(func, diff);
}
여기에 몇 가지 설명이 있습니다. http://closure-library.googlecode.com/svn/docs/closure_goog_timer_timer.js.source.html
시간 초과 값이 너무 커서 부호있는 32 비트 정수에 맞지 않을 경우 FF, Safari 및 Chrome에서 오버플로가 발생하여 시간 초과가 즉시 예약 될 수 있습니다. 24.8 일은 브라우저가 열린 상태로 유지 될 수있는 합리적인 기대치를 초과하므로 이러한 시간 제한을 예약하지 않는 것이 더 합리적입니다.
setTimeout()
할 날짜와 시간을 계산하고 무작위로 정의 된 틱에서 카운터를 줄이지 않기를 바랍니다. 적어도)
여기에서 Timers의 노드 문서를 확인하세요 : https://nodejs.org/api/timers.html (현재 이벤트 루프 기반에서 이러한 보편적 인 용어이기 때문에 js에서도 동일하다고 가정 합니다.
요컨대 :
지연이 2147483647보다 크거나 1보다 작 으면 지연이 1로 설정됩니다.
지연은 다음과 같습니다.
콜백을 호출하기 전에 대기하는 시간 (밀리 초)입니다.
시간 초과 값이 이러한 규칙에 따라 예상치 못한 값으로 기본 설정되는 것 같습니다.
만료 된 세션으로 사용자를 자동으로 로그 아웃하려고 할 때이 문제를 발견했습니다. 내 솔루션은 하루 후에 시간 제한을 재설정하고 clearTimeout을 사용하도록 기능을 유지하는 것입니다.
다음은 약간의 프로토 타입 예제입니다.
Timer = function(execTime, callback) {
if(!(execTime instanceof Date)) {
execTime = new Date(execTime);
}
this.execTime = execTime;
this.callback = callback;
this.init();
};
Timer.prototype = {
callback: null,
execTime: null,
_timeout : null,
/**
* Initialize and start timer
*/
init : function() {
this.checkTimer();
},
/**
* Get the time of the callback execution should happen
*/
getExecTime : function() {
return this.execTime;
},
/**
* Checks the current time with the execute time and executes callback accordingly
*/
checkTimer : function() {
clearTimeout(this._timeout);
var now = new Date();
var ms = this.getExecTime().getTime() - now.getTime();
/**
* Check if timer has expired
*/
if(ms <= 0) {
this.callback(this);
return false;
}
/**
* Check if ms is more than one day, then revered to one day
*/
var max = (86400 * 1000);
if(ms > max) {
ms = max;
}
/**
* Otherwise set timeout
*/
this._timeout = setTimeout(function(self) {
self.checkTimer();
}, ms, this);
},
/**
* Stops the timeout
*/
stopTimer : function() {
clearTimeout(this._timeout);
}
};
용법:
var timer = new Timer('2018-08-17 14:05:00', function() {
document.location.reload();
});
그리고 stopTimer
방법으로 지울 수 있습니다 .
timer.stopTimer();
Number.MAX_VALUE
실제로 정수가 아닙니다. setTimeout의 최대 허용 값은 2 ^ 31 또는 2 ^ 32입니다. 시험
parseInt(Number.MAX_VALUE)
1.7976931348623157e + 308 대신 1 개를 돌려받습니다.
Number.MAX_VALUE
정수입니다. 뒤에 0이 292 개있는 정수 17976931348623157입니다. parseInt
반환 되는 이유 는 1
먼저 인수를 문자열로 변환 한 다음 문자열을 왼쪽에서 오른쪽으로 검색하기 때문입니다. .
(숫자가 아닌)를 찾으면 바로 멈 춥니 다.
Number.isInteger(foo)
. 그러나 아직 지원되지 않으므로 Math.round(foo) === foo
대신 사용할 수 있습니다 .
Number.MAX_VALUE
은 정수가 아니라 double
. 그래서 ... double은 정수를 나타낼 수 있습니다. JavaScript에서 32 비트의 정수를 저장하는 데 사용되기 때문입니다.
Number.MAX_VALUE
하면 정수가 아닙니다. 그러나 "정수"가 "정수"의 정신적 개념을 의미한다면 그것은 정수입니다. JavaScript에서는 모든 숫자가 64 비트 부동 소수점이므로 "정수"라는 정신적 개념 정의를 사용하는 것이 일반적입니다.
Number.MAX_SAFE_INTEGER
여기에서 찾고있는 숫자가 아닙니다.
delay >>> 0
일이 발생하므로 전달 된 지연은 0입니다. 어느 쪽이든 지연이 32 비트 unsigned int로 저장된다는 사실이이 동작을 설명합니다. 감사!