Значение таймера setTimeout может быть расширено

Привет всем, я знаю, что это просто и глупо спрашивать, но этот вопрос съедает меня. Если у меня есть следующий код ниже.

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

Daniel A. White 08.04.2019 17:36
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
1
826
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ну, в общем, чтобы иметь возможность «продлить» таймер, вам нужно отменить его (используя 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);

Другие вопросы по теме