setInterval控制台正常但浏览器数据不更新,Node.js代理API定时刷新问题
Hey there! Let's work through your two technical problems with clear, actionable solutions:
Issue 1: setInterval() works in console but stops updating browser data after one API call
What's likely going wrong
There are a few common culprits here:
- Scope issues: Your
setIntervalmight be getting garbage collected or its reference lost after the first API call, especially if it's defined inside a function that only runs once. - Uncaught errors in API calls: If the API call throws an error after the first run, it could break subsequent executions of your interval callback—uncaught errors in async code can halt the interval entirely.
- DOM update logic isn't triggering: You might be fetching new data but failing to update the DOM to reflect it. Maybe you're reusing the same DOM element reference without re-rendering, or your update code is blocked by another operation.
- setInterval vs async operations:
setIntervaldoesn't wait for async API calls to finish before firing again. If the first API call takes longer than 30 seconds, you could end up with overlapping requests, causing race conditions or data conflicts that break updates.
Fixes to try
- Use recursive setTimeout instead of setInterval (safer for async workflows):
const fetchAndUpdateData = async () => { try { // Fetch data from your API const response = await fetch('your-api-endpoint'); const data = await response.json(); // Update DOM with new data document.getElementById('score-display').textContent = data.latestScore; } catch (err) { console.error('Failed to fetch/update data:', err); } // Schedule next run only after current operation finishes setTimeout(fetchAndUpdateData, 30000); }; // Start the update loop fetchAndUpdateData(); - Keep your interval reference in a global scope (if you prefer setInterval):
// Declare interval variable globally to avoid losing reference let scoreUpdateInterval; const startScoreUpdates = () => { scoreUpdateInterval = setInterval(async () => { try { const data = await fetchYourScoreData(); updateScoreDOM(data); } catch (err) { console.error('Update failed:', err); } }, 30000); }; // Initialize the interval startScoreUpdates(); - Add robust error handling: Always wrap async API calls in
try/catchto prevent uncaught errors from breaking your interval loop. - Validate DOM updates: Console.log the fetched data to confirm it's changing, then double-check that your DOM update code is targeting the correct elements and running as expected.
Issue 2: Build a Node.js API that caches remote cricket scores (auto-refresh every 30s)
The goal here is to create an API that periodically fetches data from the remote source, stores it in a cache, and serves this cached data to users—so you don't hit the remote API on every user request (reducing their load).
Step-by-step solution
- Use an in-memory cache (or Redis for production) to store the latest score data.
- Set up a periodic fetch with
setIntervalto refresh the cache every 30 seconds. - Create an Express endpoint that returns the cached data to users.
Full code example
Note: The request library is deprecated, so I'll use node-fetch (install it with npm install node-fetch):
const express = require("express"); const app = express(); const fetch = require("node-fetch"); // In-memory cache to store the latest cricket scores let cachedScores = null; // Function to fetch data from remote API and update cache const refreshScores = async () => { try { const response = await fetch('https://remote-cricket-api.com/scores'); if (!response.ok) throw new Error(`Remote API error: ${response.status}`); cachedScores = await response.json(); console.log('Cache updated:', new Date().toLocaleTimeString()); } catch (err) { console.error('Failed to refresh scores:', err); // Keep old cache data instead of clearing it, so users still get valid responses } }; // Initial fetch to populate cache when app starts refreshScores(); // Schedule auto-refresh every 30 seconds setInterval(refreshScores, 30000); // API endpoint for users to get cached scores app.get('/api/cricket-scores', (req, res) => { if (!cachedScores) { return res.status(503).json({ error: 'Scores not available yet. Try again in a few seconds.' }); } res.json(cachedScores); }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`API running on port ${PORT}`); });
Key notes
- Error resilience: If the remote API fails, we retain the last valid cached data so users don't get an error response.
- Initial load: We call
refreshScores()once on app start to ensure the cache isn't empty for the first user request. - Scalability: For production apps with multiple API instances, replace the in-memory cache with Redis (a distributed cache) to share cached data across all instances.
内容的提问来源于stack exchange,提问作者aviral garg
相关产品推荐
相关产品推荐

