Si j'ai un tableau d'URL:
var urls = ['1.txt', '2.txt', '3.txt']; // these text files contain "one", "two", "three", respectively.
Et je veux construire un objet qui ressemble à ceci:
var text = ['one', 'two', 'three'];
J’essaie d’apprendre à faire cela avec fetch
, qui renvoie bien sûr Promise
s.
Certaines choses que j’ai essayées ne pas fonctionnent:
var promises = urls.map(url => fetch(url));
var texts = [];
Promise.all(promises)
.then(results => {
results.forEach(result => result.text()).then(t => texts.Push(t))
})
Cela ne semble pas correct et, dans tous les cas, cela ne fonctionne pas - je ne me retrouve pas avec un tableau ['un', 'deux', 'trois'].
Utilise Promise.all
la bonne approche ici?
Oui, Promise.all
est la bonne approche, mais vous en avez réellement besoin deux fois si vous voulez d'abord fetch
toutes les urls puis obtenir tous les text
s (qui sont à nouveau des promesses pour le corps de la réponse) . Donc tu devrais faire
Promise.all(urls.map(u=>fetch(u))).then(responses =>
Promise.all(responses.map(res => res.text()))
).then(texts => {
…
})
Votre code actuel ne fonctionne pas car forEach
ne renvoie rien (ni tableau ni promesse).
Bien sûr, vous pouvez simplifier cela et commencer par obtenir le corps de chaque réponse juste après la promesse de récupération respective remplie:
Promise.all(urls.map(url =>
fetch(url).then(resp => resp.text())
)).then(texts => {
…
})
Pour une raison quelconque, aucun des exemples de Bergi n'a fonctionné pour moi. Cela me donnerait simplement des résultats vides. Après un peu de débogage, il semble que la promesse reviendrait avant la fin de la récupération, d'où des résultats vides.
Cependant, Benjamin Gruenbaum avait une réponse ici plus tôt, mais l'a supprimée. Sa méthode a a fonctionné pour moi, je vais donc simplement la copier-coller ici, au cas où quelqu'un d'autre rencontrerait un problème avec la première solution ici.
var promises = urls.map(url => fetch(url).then(y => y.text()));
Promise.all(promises).then(results => {
// do something with results.
});
Vous devriez utiliser map
au lieu de forEach
:
Promise.all(urls.map(url => fetch(url)))
.then(resp => Promise.all( resp.map(r => r.text()) ))
.then(result => {
// ...
});