Как решить проблему утечки памяти settimeout в JavaScript - PullRequest
0 голосов
/ 06 мая 2019

У меня есть такая функция JS

function check() {
    ...do something
}

Теперь я хочу запустить ее при запуске сценария и при запуске каждый день (00:00:01 каждый день).Мой код теперь выглядит следующим образом

function check() {
    ...do something

    let today = new Date();
    let tomorrow = new Date();
        tomorrow.setHours(0,0,1,0);
        tomorrow.setDate(tomorrow.getDate()+1);

    console.log("next check in", tomorrow-today);
    setTimeout(() => { check() }, tomorrow-today);
}
check();

Я использую setTimeout внутри check ().Я думаю, что это плохой код, потому что он создаст цикл, и функция check () никогда не будет очищена.Как это исправить?

Ответы [ 2 ]

2 голосов
/ 06 мая 2019

Вы правы, что неконтролируемая рекурсия может привести к исчерпанию ресурсов из-за бесконечного роста стека. Например, следующая программа Javascript будет аварийно завершена после того, как check() будет выполнено достаточное количество раз без первого return ing:

function check() {
  check();
}
check();

Следующий код не завершится таким образом:

function check() {
  setTimeout(check, 1000);
}
check();

Этот код может выполняться бесконечно, не исчерпывая стек, потому что каждый раз, когда запускается check(), разрешается запуск до завершения и return до его запуска в будущем.

Это работает, потому что функция setTimeout() напрямую не запускается check(). Вместо этого он сообщает среде выполнения Javascript запланировать выполнение check() на 1 секунду в будущем. Когда он и check() завершены, стек Javascript становится пустым. Через 1 секунду выполнение check() ставится в очередь и в конечном итоге выполняется , пока стек Javascript свободен.

Поскольку стек Javascript должен быть очищен до запуска check(), переполнения стека исключаются.

0 голосов
/ 06 мая 2019

Вы можете добавить функцию clearTimeout (таймер):

let timer = setTimeout(() => check());

clearTimeout(timer);
...