Muy bien, tengo las siguientes 3 funciones que me ayudan a recopilar géneros de Spotify basados en ID de artistas. Dado que la mayoría de las pistas en Spotify tienen varios artistas, necesito combinar todos los géneros de artistas individuales para poder usarlos en un momento posterior.
Tengo las siguientes 3 funciones:
const getArtist = async (artistId) => { console.log('4'); const artistObject = await getData( 'https://api.spotify.com/v1/artists/' + artistId ).then((artistObject) => { return artistObject; }); }; const getAllGenres = (artists) => { let artistGenres = []; console.log('2'); artists.map(async (item) => { console.log('3'); await getArtist(item.id).then(async (artist) => { console.log('5'); await artist.genres.map((genre) => { if (artistGenres.indexOf(genre) == -1) { artistGenres.push(genre); } }); }); }); return artistGenres; };Y
const getGenre = (artists) => { console.log('1'); const allgenres = getAllGenres(artists); console.log('6', allgenres); } Cada vez que verifico el valor de todos los allgenres en la consola, parece vacío, pero cada vez que hago clic en la flecha para desplegarlo, tiene valor. Sé que esto se debe a que revalida el valor de todos los allgenres cada vez que despliego la matriz.
Busqué soluciones en línea con respecto a esto y encontré async/await. Intenté esto y tuve que cambiar getAllGenres en una promesa. No es un problema, pero no resolvió el problema.
He agregado algunos console.logs para ayudarme a comprender el flujo actual de ejecución:
1 2 3 4 3 4 6 [] <- Revalidates after opening 5 5Según tengo entendido, console.log (6) debería ser el último en ejecutarse, pero este no es el caso.
Como se le sugirió, no mezcle la sintaxis then y async/await , ya que hace que el código sea más difícil de leer, no puedo probar el código ya que no tengo acceso a esa API, pero esto debería funcionar:
const getArtist = (artistId) => { return getData('https://api.spotify.com/v1/artists/' + artistId); }; const getAllGenres = async (artists) => { let artistGenres = []; await Promise.all( artists.map(async (item) => { const artist = await getArtist(item.id); artist.genres.forEach((genre) => { if (artistGenres.indexOf(genre) == -1) { artistGenres.push(genre); } }); }) ); return artistGenres; }; const getGenre = async (artists) => { const allgenres = await getAllGenres(artists); console.log(allgenres); };getArtist no necesita ser asíncrono ya que getData debe ser una función asíncrona que devuelve una promesa, por lo que getArtist devolverá una promesa automáticamente.getGenre , por otro lado, debe ser asíncrono, ya que necesita esperar para recuperar todos los géneros antes de usarlos, y eso sucede de forma asíncrona.getAllGenres es donde debe tener cuidado, va a lanzar varias llamadas asíncronas en paralelo, ese es un escenario que debe manejar con Promise.all , encontrará muchos recursos aquí en SO sobre este tema específico.