大家好我知道这是基本而愚蠢的问题,但这个问题让我感到厌烦。如果我有以下代码。
var timerVal = 900000
function myFunction() {
setTimeout(function(){ alert("Hello"); }, timerVal);
}
myFunction()
根据上面的代码,警报将在15分钟后发出。但十分钟之后,我想通过将timerVal的值更改为1200000来将其延长5分钟。现在警报将在另外10分钟之后到来。即在警报到来后总共20分钟,或者在完成15分钟后到达。假设代码是这样的:
var timerVal = 900000
function myFunction() {
setTimeout(function(){ alert("Hello"); }, timerVal);
}
function change(){
setTimeout(function(){
timerVal = 1200000;
},60000);
}
myFunction();
change();
任何人都可以让我知道结果会是什么,并简要说明原因?
结果将是定时器将在900000
毫秒标记处执行,尽管您已尝试通过更改1200000
变量的值将其更改为timerVal
毫秒。
这是因为在JavaScript中,它是按值传递的,因为您最初通过了900000
,计时器已经在900000
排队,因此无法通过再次更改timerVal
变量的值来更改。
所以这段代码,只是让timerVal
指向新的数字1200000
并没有真正改变之前设置的超时:
function change(){
setTimeout(function(){
timerVal = 1200000; //timerVal reference is pointing to a new number
}, 60000);
}
要真正更改计时器行为,您需要使用setTimeout
调用返回的id清除超时,并使用新的超时值创建另一个。
let timerVal = 9000;
function myFunction() {
return setTimeout(function(){ alert("Hello"); }, timerVal); //returning the id
}
function change(id, newVal){
clearTimeout(id); //clearing the previous timer using the id
setTimeout(function(){ alert("Hello"); }, newVal);
}
let id = myFunction();
change(id, 5000);
AFAIU,你不能延长setTimeout的时间。您可以做的是停止执行,并使用新值创建另一个setTimeout。像这样:
var timer = setTimeout(()=>console.log("first"), 2000);
clearTimeout(timer);
var timer = setTimeout(()=>console.log("second"), 2000);
您无法扩展它,因为计时器是使用变量在创建事件时具有的值创建的。它不是可以不时评估的参考。它是一个固定值,仅在创建时评估。
好吧,一般来说,为了能够“扩展”一个计时器,你需要取消它(使用clearTimeout
),并重新创建它。为此,您需要跟踪自最初开始以来经过多长时间并计算新时间。
下面的代码演示了一个函数extendableTimeout
,它可以像普通的setTimeout
一样使用,除了它返回一个带有extend
函数的对象,你可以将它用于你的目的。
该演示有2个按钮,第一个启动延迟5秒的动作。单击“扩展”按钮可将超时时间再延长5秒。您可以比较单击延伸或不查看时间。
function extendableTimeout(fn, time){
var id = setTimeout(fn, time);
var timeStart = new Date();
return {
timerId: id,
extend: function(time){
clearTimeout(id);
var elapsed = new Date() - timeStart;
var newTime = time - elapsed;
setTimeout(fn,newTime);
}
}
}
var myTimer;
$('#start').on("click", function(){
console.log("Started at " + new Date());
myTimer = extendableTimeout(() => console.log("Finished at " + new Date()), 5000);
})
$("#extend").on("click", function(){
myTimer.extend(10000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="start">Start</button>
<button id="extend"> + 5s </button>