URLの配列がある場合:
var urls = ['1.txt', '2.txt', '3.txt']; // these text files contain "one", "two", "three", respectively.
そして、次のようなオブジェクトを作成します。
var text = ['one', 'two', 'three'];
私はfetch
でこれを行うことを学ぼうとしていますが、もちろんPromise
sを返します。
私が試したいくつかのことしない仕事:
var promises = urls.map(url => fetch(url));
var texts = [];
Promise.all(promises)
.then(results => {
results.forEach(result => result.text()).then(t => texts.Push(t))
})
これは正しく見えず、いずれの場合でも機能しません。配列['one'、 'two'、 'three']にはなりません。
使用しています Promise.all
ここで正しいアプローチ?
はい、 Promise.all
は正しいアプローチですが、最初にfetch
すべてのURLを取得し、次にそれらからすべてのtext
sを取得する場合は、実際に2回必要です(これも応答の本文の約束です) 。だからあなたはする必要があります
Promise.all(urls.map(u=>fetch(u))).then(responses =>
Promise.all(responses.map(res => res.text()))
).then(texts => {
…
})
forEach
は何も返さない(配列でもプロミスでもない)ため、現在のコードは機能していません。
もちろん、それを単純化して、それぞれのフェッチプロミスが満たされた直後に各応答から本文を取得することから始めることができます。
Promise.all(urls.map(url =>
fetch(url).then(resp => resp.text())
)).then(texts => {
…
})
なんらかの理由で、ベルギの例はどちらもうまくいきませんでした。単純に空の結果が得られます。デバッグ後、フェッチが完了する前にプロミスが返されるように見えるため、結果は空になります。
しかし、ベンジャミン・グリュンバウムは以前ここで答えを持っているが、それを削除した。彼の方法did私のために働くので、ここで最初の解決策で他の誰かが問題に遭遇した場合の代替として、ここにコピーアンドペーストします。
var promises = urls.map(url => fetch(url).then(y => y.text()));
Promise.all(promises).then(results => {
// do something with results.
});
map
の代わりにforEach
を使用する必要があります。
Promise.all(urls.map(url => fetch(url)))
.then(resp => Promise.all( resp.map(r => r.text()) ))
.then(result => {
// ...
});