Запуск действия из setInterval, когда вкладка скрыта

#javascript #google-chrome #browser #timer

#javascript #google-chrome #браузер #таймер

Вопрос:

Chrome объявил, что его новая версия еще больше ограничит таймеры. Каков рекомендуемый способ, с помощью которого я могу гарантировать, что определенное действие (запрос API) вызывается через X миллисекунд, если вкладка все еще активна, но скрыта?

Комментарии:

1. Предоставленная вами ссылка уже содержит рекомендации и описывает алгоритмы, когда и как будут регулироваться таймеры. Также в JavaScript даже для видимой страницы нет гарантии, что таймер будет вызван ровно через N миллисекунд

2. Привет @maksimr. Действительно, они предлагают некоторые решения, но я не вижу четкого решения для моего случая. В то же время я не ищу очень точный таймер ( /- 1 с разумно). Пример варианта использования: пользователь получает форму и 30 минут на ее заполнение, в конце чего я хочу выполнить вызов API. Вместо того, чтобы обманывать браузер, заставляя его думать, что вкладка активна (сердцебиение через веб-сокеты, низкочастотный звук, воспроизводимый в цикле, И т. Д.), Мне было интересно, есть ли четкая рекомендация для достижения этой цели. Спасибо!

3. И я предполагаю, что это также «академическое» любопытство, чтобы посмотреть, действительно ли это возможно.

4. Для вашего варианта использования, если я правильно понял, не является ли это просто функцией асинхронного ожидания с конечным условием, определяющим, завершена ли форма. Как только проблема wait будет решена, выполните вызов API.

5. @DanOvidiuBoncut похоже, вы устанавливаете только один таймер, верно? Если вы не связываете свои таймеры (используя setInterval или вызывая setTimeout внутри setTimeout), то в отправленной вами ссылке указано, что они будут регулироваться таким образом, чтобы они проверялись один раз в секунду. Интенсивное регулирование происходит только после того, как длина цепочки составляет 5 или более.

Ответ №1:

wait Функция, о которой я сказал, похожа

 function wait(timeoutInMilliseconds, waitConditionFunc, interval=50) {
    const date = new Date();
    if (timeoutInMilliseconds > 0) {
        date.setMilliseconds(date.getMilliseconds()   timeoutInMilliseconds);
    }
    return new Promise((resolve, reject) => {
        if (!waitConditionFunc || !waitConditionFunc()) {
            //if there is no condition, or after checking the condition, we don't need to wait, resolve
            resolve();
        }

        //check the condition intervally until the condition func indicates that we don't need to wait, or time out
        let intervalId = setInterval(() => {
            if (!waitConditionFunc || !waitConditionFunc()) {
                //if there is no condition, or after checking the condition, we don't need to wait, resolve
                clearInterval(intervalId);
                resolve();
            }
            if (timeoutInMilliseconds > 0 amp;amp; Date.now() >= date) {
                //time out
                clearInterval(intervalId);
                reject("timeout");
            }
        }, interval);
    });
}
 

Вы можете вызвать wait , передав, скажем, 3600000 (1 час или передача 0 без тайм-аута), а также функцию проверки формы (или передачи null для просто ожидания в течение 1 часа). Надеюсь, я правильно понял ваш вопрос, и эта функция помогает.