如何等待循环内的Promise完成后再返回,解决数组为空问题
movieList Only After Async Requests Complete Hey Henrik, let's break down why your movieList is empty when you try to loop through it. The core problem is asynchronous execution behavior—$.getJSON doesn't block your code while it fetches data from the API. Instead, it runs in the background, and the rest of your script continues immediately. That means you're trying to iterate over movieList before the API response has arrived and populated the array.
Here are two reliable ways to fix this:
1. Handle Iteration Inside the Request Callback
The simplest approach is to move all code that depends on the API data (like your movieList iteration) inside the $.getJSON callback function. This ensures it only runs after the request finishes and the array is populated. If you need to fetch both movie and genre data, you can nest the requests like this:
var url = "https://api.themoviedb.org/3/movie/popular?api_key=2c2a6a5ed606126f48db4cdbca91c0f0&language=en-US&page=1"; var genreUrl = "https://api.themoviedb.org/3/genre/movie/list?api_key=2c2a6a5ed606126f48db4cdbca91c0f0"; var movieList = []; // Fetch popular movies first $.getJSON(url, function(movieData) { // Populate movieList with raw movie data movieData.results.forEach(function(movie) { movieList.push({ id: movie.id, title: movie.title, genre_ids: movie.genre_ids }); }); // Fetch genre data to map to movies $.getJSON(genreUrl, function(genreData) { // Add genre names to each movie object movieList.forEach(function(movie) { movie.genres = genreData.genres .filter(genre => movie.genre_ids.includes(genre.id)) .map(genre => genre.name); }); // NOW we can safely iterate over movieList movieList.forEach(function(movie) { console.log(`Movie: ${movie.title} | Genres: ${movie.genres.join(', ')}`); }); }); });
2. Use Promises + Async/Await (Cleaner for Multiple Requests)
If you have multiple asynchronous requests, nested callbacks can get messy (this is called "callback hell"). A better approach is to wrap $.getJSON in Promises and use async/await to write linear, easy-to-read code:
var url = "https://api.themoviedb.org/3/movie/popular?api_key=2c2a6a5ed606126f48db4cdbca91c0f0&language=en-US&page=1"; var genreUrl = "https://api.themoviedb.org/3/genre/movie/list?api_key=2c2a6a5ed606126f48db4cdbca91c0f0"; // Wrap $.getJSON in a Promise for async/await compatibility function fetchApiData(apiUrl) { return new Promise((resolve, reject) => { $.getJSON(apiUrl, resolve).fail(reject); }); } // Async function to handle the entire workflow async function processMovieData() { try { // Fetch both movie and genre data in parallel (faster than sequential) const [movieData, genreData] = await Promise.all([ fetchApiData(url), fetchApiData(genreUrl) ]); // Build movieList with merged genre data const movieList = movieData.results.map(movie => { const genreNames = genreData.genres .filter(genre => movie.genre_ids.includes(genre.id)) .map(genre => genre.name); return { id: movie.id, title: movie.title, genres: genreNames }; }); // Iterate over the fully populated movieList movieList.forEach(movie => { console.log(`Movie: ${movie.title} | Genres: ${movie.genres.join(', ')}`); }); } catch (error) { console.error("Error fetching data:", error); } } // Run the async function processMovieData();
Key Takeaway
Always make sure any code that relies on asynchronous data runs after the request has completed. Whether you use callbacks or async/await, the goal is to wait for the API response before accessing or iterating over movieList.
内容的提问来源于stack exchange,提问作者Henrik S

