Je construis un jeu de quiz musical idiot pour apprendre. Je dois remplir ma vue avec de la musique associée à partir de deezer api .
Ce dont j'ai besoin:
Donc, j'ai trouvé ma voie a > jusqu'à l'étape 3
Mais je ne trouve pas comment envoyer correctement la même demande 4 fois (pour chaque artiste), et mes recherches ne m'ont rien donné jusqu'à présent
function deezer() { const reqGenero = new Request('https://api.deezer.com/genre'); fetch(reqGenero) .then(response => { if (response.status === 200) { return response.json(); } else { throw new Error('Erro ao pegar gêneros'); } }) .then(generos => { /* pega genero aleatorio */ var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id; //console.log('\ngenero... ' + generoId); return fetch('https://api.deezer.com/genre/' + generoId + '/artists') }) .then(response => { if (response.status === 200) { return response.json(); } else { throw new Error('Erro ao pegar artistas'); } }) .then(artistas => { /* 1 música de 4 artistas */ var artistasIds = []; for(var i = 0; i <= 4; i++) { artistasIds.push(artistas.data[i].id); console.log('\nId: ' + artistasIds[i]); // CAN I SEND THIS REQUEST 4 TIMES? return fetch('https://api.deezer.com/artist/' + ids + '/top'); } }) .catch(error => { console.error(error); }); }
4 Réponses :
Vous pouvez créer 4 requêtes et attendre qu'elles soient toutes terminées , en utilisant Promise # all .
.then(artistas => { /* 1 música de 4 artistas */ const artistasPromises = artistas.data.map(artista => fetch("https://api.deezer.com/artist/" + artista.id + "/top").catch( err => ({ error: err }) ) ); return Promise.all(artistasPromises); }).then(musicList => { console.log(musicList); });
Notez le catch ()
. Cela garantit que même si une extraction échoue, les autres résultats de l'extraction ne sont pas ignorés. Cela est dû à la façon dont Promise # all fonctionne. Ainsi, vous devez parcourir musicList
et vérifier s'il existe un objet de la forme {error: / * error object * /}
et l'ignorer lors du traitement de la liste.
Vous pouvez remplacer l'instruction
const fetchResults = []; artistasIds.forEach(function(ids){ fetchResults.push(fetch('https://api.deezer.com/artist/' + ids + '/top')); }); return Promise.all(fetchResults);
par
// CAN I SEND THIS REQUEST 4 TIMES? return fetch('https://api.deezer.com/artist/' + ids + '/top');
dans puis condition vous obtiendrez un tableau de valeurs avec la meilleure musique de chaque artiste. Je n'ai pas vérifié avec l'API donnée, mais idéalement, cela devrait fonctionner.
Oui, vous pouvez faire 5 requêtes (pas 4 ses 0-4) et attendre que chacune se termine. Utilisez Array.prototype.map pour créer un tableau de demandes de promesses (préférez for- forEach et array.push)
et Promise.all d'attendre que toutes les promesses se terminent, ce qui renverra le tableau des réponses résolues, si aucun échec.
.then(artistas => { /* 1 música de 4 artistas */ var artistasIds = []; let ids = artistas.data.map(artist => artist.id).slice(0, 4); requests = ids.map(id => fetch(`https://api.deezer.com/artist/${id}/top`)); return Promise.all(requests); } })
Si vous utilisez les promesses explicitement (voir ci-dessous pour les fonctions async
), je l'aborderais probablement comme ceci; voir les commentaires de ***
pour l'explication:
// *** Give yourself a helper function so you don't repeat this logic over and over async function fetchJson(errmsg, ...args) { const response = await fetch(...args) if (!response.ok) { // *** .ok is simpler than .status == 200 throw new Error(errmsg); } return response.json(); } async function deezer() { const reqGenero = new Request('https://api.deezer.com/genre'); const generos = await fetchJson('Erro ao pegar gêneros', reqGenero); var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id; //console.log('\ngenero... ' + generoId); const artistas = await fetchJson('Erro ao pegar artistas', 'https://api.deezer.com/genre/' + generoId + '/artists'); /* 1 música de 4 artistas */ // *** Use Promise.all to wait for the four responses return Promise.all(artistas.data.slice(0, 4).map( entry => fetchJson('Erro ao pegar música', 'https://api.deezer.com/artist/' + entry.id + '/top') )); }
Cela suppose que vous voulez utiliser les résultats dans deezer
. Si vous voulez que deezer
renvoie les résultats (une promesse des quatre chansons), alors:
// *** Give yourself a helper function so you don't repeat this logic over and over function fetchJson(errmsg, ...args) { return fetch(...args) .then(response => { if (!response.ok) { // *** .ok is simpler than .status == 200 throw new Error(errmsg); } return response.json(); }); } function deezer() { const reqGenero = new Request('https://api.deezer.com/genre'); return fetchJson('Erro ao pegar gêneros', reqGenero) // *** Note the return .then(generos => { /* pega genero aleatorio */ var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id; //console.log('\ngenero... ' + generoId); return fetchJson('Erro ao pegar artistas', 'https://api.deezer.com/genre/' + generoId + '/artists') }) .then(artistas => { /* 1 música de 4 artistas */ // *** Use Promise.all to wait for the four responses return Promise.all(artistas.data.slice(0, 4).map( entry => fetchJson('Erro ao pegar música', 'https://api.deezer.com/artist/' + entry.id + '/top') )); }); // *** No `then` using the results here, no `catch`; let the caller handle it }
Le async version de la fonction de ce second:
// *** Give yourself a helper function so you don't repeat this logic over and over function fetchJson(errmsg, ...args) { return fetch(...args) .then(response => { if (!response.ok) { // *** .ok is simpler than .status == 200 throw new Error(errmsg); } return response.json(); }); } function deezer() { // *** Not sure why you're using Request here? const reqGenero = new Request('https://api.deezer.com/genre'); fetchJson('Erro ao pegar gêneros', reqGenero) .then(generos => { /* pega genero aleatorio */ var generoId = generos.data[Math.floor(Math.random() * 10 + 1)].id; //console.log('\ngenero... ' + generoId); return fetchJson('Erro ao pegar artistas', 'https://api.deezer.com/genre/' + generoId + '/artists') }) .then(artistas => { /* 1 música de 4 artistas */ // *** Use Promise.all to wait for the four responses return Promise.all(artistas.data.slice(0, 4).map( entry => fetchJson('Erro ao pegar música', 'https://api.deezer.com/artist/' + entry.id + '/top') )); }) .then(musica => { // *** Use musica here, it's an array of the music responses }) .catch(error => { console.error(error); }); }
typo return fetch (... args)
doit être return fetch (args)
.
@AZ_ - Non, ça ne devrait pas. Si vous passez plus de deux arguments à fetchJson
, nous voulons étaler le paramètre rest lors de l'appel de fetch
.