Un titre un peu ambigu, mais je vais vous expliquer ...
Je fais un appel fetch à 4 URL différentes de The Movie Database .
Une fois que ces appels de récupération récupèrent les données, il setState et met à jour mon état initial. Cependant, je ne veux pas que ma page se charge tant que toutes les données ne sont pas récupérées, j'utilise donc Promise.all (ou j'essaie de le faire).
Mon code jusqu'à présent ...
state = {
movies: {
trending: {},
topRated: {},
nowPlaying: {},
upcoming: {},
},
};
const allMovieURLs = {
trending: `https://api.themoviedb.org/3/trending/all/day?api_key=${API_KEY}`,
topRated: `https://api.themoviedb.org/3/movie/top_rated?api_key=${API_KEY}&language=en-US&page=1`,
nowPlaying: `https://api.themoviedb.org/3/movie/now_playing?api_key=${API_KEY}&language=en-US&page=1`,
upcoming: `https://api.themoviedb.org/3/movie/upcoming?api_key=${API_KEY}&language=en-US&page=1`
};
//initialize an empty array to Promise.all on
const promiseArr = [];
//loop through movie URLs, call fetch + json()
for (const movies in allMovieURLs) {
//create an object that directly describes the data you get back from the url with a key
const obj = {
[movies]: fetch(allMovieURLs[movies]).then(res => res.json())
};
//push that object into an array so you can use Promise.all
promiseArr.push(obj);
Maintenant, ce que j'ai ici est un tableau ( promiseArr ) d'objets qui avoir la bonne clé avec la bonne Promise stockée à l'intérieur.
Mon prochain plan allait être d'appeler Promise.all sur eux, mais J'ai besoin d'un éventail de promesses. Après avoir récupéré les données réelles des appels d'URL, je voulais les stocker dans l'objet, dans la bonne clé correspondante?
Je suis bloqué dans cette partie depuis quelques heures maintenant .. .Toutes les astuces seraient appréciées!
3 Réponses :
Vous pouvez utiliser async / await et Object.entries () pour convertir un objet JavaScript brut en un tableau de tableaux de paires clé, valeur
(async() => {
for (const [movie, url] of Object.entries(allMovieURLs)) {
try {
allMovieURLs[movie] = await fetch(url).then(res => res.json())
.catch(e => {throw e})
} catch(e) {
console.error(e)
}
}
})()
N'appelez pas alors lors de l'ajout au tableau de promesse. Appelez-le plutôt en promesse tout
const trending = fetch(trending);
...
Promise.all([trending, topRated, nowplaying, upcoming]).then(([trending, topRated, nowplaying, upcoming]) => {
movies.trending = trending.json();
....
});
Vous pouvez simplement stocker les promesses elles-mêmes dans un autre tableau.
function fetch() {
var time = Math.random() * 1E3;
return new Promise(function (res, rej) {
setTimeout(function () {
res(time);
}, time);
});
}
const API_KEY = "";
const allMovieURLs = {
trending: `https://api.themoviedb.org/3/trending/all/day?api_key=${API_KEY}`,
topRated: `https://api.themoviedb.org/3/movie/top_rated?api_key=${API_KEY}&language=en-US&page=1`,
nowPlaying: `https://api.themoviedb.org/3/movie/now_playing?api_key=${API_KEY}&language=en-US&page=1`,
upcoming: `https://api.themoviedb.org/3/movie/upcoming?api_key=${API_KEY}&language=en-US&page=1`
};
const promiseArr = [];
const promises = [];
for (const movies in allMovieURLs) {
const obj = { [movies]: undefined };
promises.push(fetch(allMovieURLs[movies]).then(res => obj[movies] = res));
promiseArr.push(obj);
}
Promise.all(promises).then(function () {
console.log(promiseArr);
});
Si ce n'est pas faisable, vous pouvez faire quelque chose comme: Promise.all (promiseArr.map (obj => Object.values (obj) [0])) p>