1. ホーム
  2. javascript

Promise.allでURLの配列を取得するにはどうすればよいですか?

2023-09-02 12:14:35

質問

私は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 は正しいアプローチですが、実際には2回必要で、もし最初に fetch を取得し、次にすべての text を取得します (これもまた、レスポンスのボディのための約束です)。ですから、あなたは次のようにする必要があります。

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 => {
    …
})

または同じものを await :

const texts = await Promise.all(urls.map(async url => {
  const resp = await fetch(url);
  return resp.text();
}));