Reputation: 482
Hi Everyone I know it is basic and silly to ask but this question is eating me up . If I have a below following code .
var timerVal = 900000
function myFunction() {
setTimeout(function(){ alert("Hello"); }, timerVal);
}
myFunction()
As per the above code an alert will come at 15 mins . But after ten minutes I thought to extend it for more 5 mins by changing the value of timerVal to 1200000. Now would the alert will come after another 10 mins . i.e. total 20 mins after the alert will come or it will come after 15 mins of the completion . Suppose the code is like this :
var timerVal = 900000
function myFunction() {
setTimeout(function(){ alert("Hello"); }, timerVal);
}
function change(){
setTimeout(function(){
timerVal = 1200000;
},60000);
}
myFunction();
change();
Can Anyone give let me know what will be the result and brief description why ?
Upvotes: 7
Views: 4124
Reputation: 16908
The result will be that the timer will be executed at the 900000
millisecond mark, although you have tried to change it to 1200000
millisecond by changing the value of the timerVal
variable.
This is because in JavaScript it is pass by value and since you have passed 900000
initially, the timer is already queued at 900000
and hence cannot be altered by changing the value of the timerVal
variable again.
So this code, is simply making the timerVal
point to the new number 1200000
not really changing the timeout set earlier:
function change(){
setTimeout(function(){
timerVal = 1200000; //timerVal reference is pointing to a new number
}, 60000);
}
To really change the timer behavior you need to clear the timeout using the id returned by the setTimeout
call and create another one with the new timeout value.
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);
Upvotes: 7
Reputation: 136104
Well, in general to be able to "extend" a timer, you'll need to cancel it (using clearTimeout
), and re-create it. For this you'll need to keep track of how long has elapsed since it originally started and calculate a new time.
The code below demonstrates a function extendableTimeout
which you can use like the normal setTimeout
, except it returns an object with an extend
function you can use for your purpose.
The demo has 2 button, the first starts an action delayed for 5s. Clicking the extend button extends the timeout by another 5 seconds. You can compare clicking the extend or not to see the timings.
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>
Upvotes: 2
Reputation: 6562
AFAIU, you cannot extend the time of a setTimeout. What you can do is stopping it from executing, and create another setTimeout with the new value. Like this:
var timer = setTimeout(()=>console.log("first"), 2000);
clearTimeout(timer);
var timer = setTimeout(()=>console.log("second"), 2000);
You cannot extend it because the timer is created with the value the variable had at the time of creation event. It's not a reference that can be evaluated from time to time. It's a fixed value that is evaluated only on creation time.
Upvotes: 1