为何Fetch首次调用报错后续正常?代码出现TypeError的原因与解决
Hey there! Let's break down exactly what's going on with your code and get it sorted out properly.
The Root Cause: Asynchronous Execution Timing
The issue all comes down to how JavaScript handles async operations like fetch. Here's the play-by-play of your first function call:
- You run
newtexttotype(), and thefetchrequest fires off to the NPS API. But network calls take time—JavaScript doesn't pause to wait for it to finish. - Right after starting the fetch, your code jumps to
console.log(newtexthere[0].description). At this point,newtextherehasn't been assigned any value yet (it'sundefined), so trying to access[0]throws that TypeError. - Later, the fetch completes, and the
thencallback runs to setnewtexthere = data.data. But by then, theconsole.loghas already failed.
Why does it work on the second call? Because after the first run, newtexthere is now populated with data from the first successful fetch. When you call the function again, even though the new fetch is still async, the console.log runs before the new request finishes—but it uses the old, already-existing value of newtexthere instead of undefined. This is a lucky side effect, not proper, reliable code!
The Fix: Wait for the Async Operation to Finish
You need to ensure you only access the fetched data after the request has completed. There are two clean ways to do this:
Option 1: Move Your Data Logic Inside the then Callback
This is the simplest fix—put any code that uses newtexthere (like your console.log) inside the second then block, so it only runs once the data is ready:
function newtexttotype () { fetch('https://developer.nps.gov/api/v1/parks?stateCode=ca&api_key=APIKEYHERE') .then(response => response.json()) .then(data => { const newtexthere = data.data; // Use a local variable instead of global (better practice!) console.log(newtexthere[0].description); // Now this runs AFTER data is loaded }) .catch(error => { // Add error handling for network failures! console.error('Oops, failed to fetch data:', error); }); }
Option 2: Use async/await for More Readable Syntax
If you prefer code that looks more "synchronous," use async/await to explicitly wait for the fetch to finish:
async function newtexttotype () { try { const response = await fetch('https://developer.nps.gov/api/v1/parks?stateCode=ca&api_key=APIKEYHERE'); const data = await response.json(); const newtexthere = data.data; console.log(newtexthere[0].description); } catch (error) { console.error('Oops, failed to fetch data:', error); } }
The await keyword tells JavaScript to pause execution until the fetch (and JSON parsing) is done, so your log statement will only run when the data is available.
Bonus: Avoid Global Variables
I changed newtexthere to a local variable in both examples—using global variables can lead to unexpected behavior (like the "works second time" fluke you saw). Keeping variables scoped to the function is a much safer practice.
内容的提问来源于stack exchange,提问作者user12159191

