Привет всем, я знаю, что это просто и глупо спрашивать, но этот вопрос съедает меня. Если у меня есть следующий код ниже.
var timerVal = 900000
function myFunction() {
setTimeout(function(){ alert("Hello"); }, timerVal);
}
myFunction()
В соответствии с приведенным выше кодом предупреждение придет через 15 минут. Но через десять минут я подумал продлить его еще на 5 минут, изменив значение timerVal на 1200000. Теперь оповещение придет еще через 10 минут. то есть всего через 20 минут после того, как придет предупреждение или оно придет через 15 минут после завершения. Предположим, код такой:
var timerVal = 900000
function myFunction() {
setTimeout(function(){ alert("Hello"); }, timerVal);
}
function change(){
setTimeout(function(){
timerVal = 1200000;
},60000);
}
myFunction();
change();
Может ли кто-нибудь дать мне знать, каков будет результат и краткое описание, почему?
Ну, в общем, чтобы иметь возможность «продлить» таймер, вам нужно отменить его (используя 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.info("Started at " + new Date());
myTimer = extendableTimeout(() => console.info("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>
AFAIU, вы не можете продлить время setTimeout. Что вы можете сделать, так это остановить его выполнение и создать еще один setTimeout с новым значением. Так:
var timer = setTimeout(()=>console.info("first"), 2000);
clearTimeout(timer);
var timer = setTimeout(()=>console.info("second"), 2000);
Вы не можете расширить его, потому что таймер создается со значением, которое переменная имела во время события создания. Это не эталон, который можно время от времени оценивать. Это фиксированное значение, которое оценивается только во время создания.
В результате таймер будет выполняться на отметке 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
, и создать еще один с новым значением тайм-аута.
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);
чтобы изменить таймер, вам нужно вызвать
clearTimeout(handle)