setTimeout计时器值可以扩展

问题描述 投票:3回答:3

大家好我知道这是基本而愚蠢的问题,但这个问题让我感到厌烦。如果我有以下代码。

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();

任何人都可以让我知道结果会是什么,并简要说明原因?

javascript
3个回答
0
投票

结果将是定时器将在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);

0
投票

AFAIU,你不能延长setTimeout的时间。您可以做的是停止执行,并使用新值创建另一个setTimeout。像这样:

var timer = setTimeout(()=>console.log("first"), 2000);

clearTimeout(timer);

var timer = setTimeout(()=>console.log("second"), 2000);

您无法扩展它,因为计时器是使用变量在创建事件时具有的值创建的。它不是可以不时评估的参考。它是一个固定值,仅在创建时评估。


0
投票

好吧,一般来说,为了能够“扩展”一个计时器,你需要取消它(使用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>
© www.soinside.com 2019 - 2024. All rights reserved.