异步API填充对象数组后转JSON为空的问题求助
问题原因与解决方案
核心问题是异步请求的执行时机:你发起的axios.get是异步操作,JavaScript会继续执行后续代码,不会等待请求完成。所以当你执行console.log(songs.items.length)和sendSongs时,所有请求还没返回,songs.items自然是空数组。而控制台里console.log(songs.items)看起来有内容,是因为浏览器会动态更新对象的显示,实际执行log时数组是空的,只是后续请求完成后数组被修改了,控制台才展示最终状态。
修改后的代码
const getArrayOfSongs = async (playlists, dataFavorites, dataProfile, accessToken) => { let songs = {"items": []}; // 收集所有请求的Promise,等待全部完成 await Promise.all(playlists.map(async (playlist) => { try { const response = await axios.get( `${PLAYLIST_ENDPOINT}${playlist.id}/tracks?limit=50&offset=0`, { headers: { Authorization: `Bearer ${accessToken}` } } ); response.data.items.forEach((song) => { if (song.track.is_local === false) { // 简化artists数组生成 const artists = song.track.artists.map(artist => artist.name); const obj = { "name": song.track.name, "id": song.track.id, "album": song.track.album.name, "artist": artists, "link": song.track.href }; // 检查是否已存在,避免重复 const index = songs.items.findIndex(item => item.id === obj.id); if (index === -1) { songs.items.push(obj); } } }); } catch (error) { console.log(error); } })); // 现在所有请求都完成,数组已填充 console.log(songs.items); console.log(songs.items.length); const user = getProfile(dataProfile); sendSongs(JSON.stringify(songs), user); }
关键改动说明
async/await处理异步:给函数加上async标记,内部用await等待每个axios.get请求完成,确保响应返回后再处理歌曲数据。Promise.all等待所有请求:把每个playlist对应的请求Promise收集到数组中,await Promise.all(...)会等待所有请求都成功完成后,才继续执行后续代码。- 简化代码逻辑:把
cutArtist函数替换成更简洁的map方法生成artists数组,减少冗余代码。 - 错误处理统一:把原来的
.catch换成try/catch,和await配合更符合异步代码的写法。
这样修改后,所有异步请求完成后才会执行后续的打印和sendSongs调用,就能拿到填充好的songs.items数组了。
内容的提问来源于stack exchange,提问作者Jorge Siqueira
相关产品推荐
相关产品推荐

