Как запустить таймер, который будет работать в фоновом режиме?

У меня есть задача: мне нужно, чтобы пользователям выдавались монетки каждые 60 секунд. Однако при закрытии вкладки таймер перестает работать, и монетки не выдаются. Как мне реализовать механизм, чтобы монетки продолжали начисляться даже при закрытии вкладки, если userId пользователя хранится в localStorage?
  • 26 октября 2024 г. 10:02
Ответы на вопрос 2
Для реализации таймера, который будет работать в фоновом режиме и выдавать монеты пользователям даже при закрытии вкладки, можно использовать веб-технологии, такие как `Web Workers` или `Service Workers`, а также базу данных (например, IndexedDB) для хранения состояния.

Вот один из подходов к реализации данной функциональности:

1. **Серверная часть**: Создайте серверное API, которое будет обрабатывать начисление монет пользователям. Когда пользователь получает монеты, информация об этом отправляется на сервер. Это позволит сохранять состояние и обеспечивать справедливое начисление даже если пользователь закрыл вкладку.

2. **Хранение времени последнего начисления**: При каждом начислении монет сохраняйте в `localStorage` или в IndexedDB время последнего начисления. Это поможет вам отслеживать, когда был последний раз начислены монеты при повторном открытии вкладки.

3. **Обработчик времени**: В вашем главном скрипте (в контексте пользовательского интерфейса) установите таймер на 60 секунд, который будет проверять, не пришло ли время начисления монет. Если пришло, то отправляйте запрос на сервер, чтобы получить монеты.

4. **Фоновая работа**: Если ваши пользователи могут оставаться активными на сайте, используйте `Background Sync API`. Это позволяет вашему приложению отправлять запросы, даже когда пользователь виртуально не активен. Однако стоит помнить, что поддержка данного API зависит от браузера.

5. **Реализация на клиенте**:

Вам может понадобиться что-то вроде этого:

```javascript
function issueCoins(userId) {
    // отправка запроса на сервер для начисления монет
    fetch('/api/issue-coins', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ userId }),
    });
}

function checkForRewards() {
    const userId = localStorage.getItem('userId');
    const lastRewardTime = localStorage.getItem('lastRewardTime') || 0;
    const currentTime = Date.now();

    if (currentTime - lastRewardTime >= 60000) {
        // Время начислить монеты
        issueCoins(userId);
        localStorage.setItem('lastRewardTime', currentTime);
    }
}

// Запуск таймера
setInterval(checkForRewards, 1000);
```

6. **Серверная часть**:

На стороне сервера создайте эндпоинт, который будет принимать запросы на начисление монет и обновлять соответствующий счет пользователя в базе данных.

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