質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

664閲覧

[javascriipt] promise.allの挙動に関して

kazuhiro_ikeda

総合スコア5

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2023/01/05 00:34

解決したいこと

promise.allにて、axiosによるGetリクエストを複数送信しています。
リクエスト数が増えると以下エラーが発生してしまい、データを取得できません。

何か回避策などご存知な方いらっしゃいましたらご教授いただきたいです。
よろしくお願いします。

エラー内容

Error occurred prerendering page "/<ルート名>". Read more: https://nextjs.org/docs/messages/prerender-error Error: getaddrinfo ENOTFOUND <ドメイン名> at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:109:26) info - Generating static pages (2/2)

補足

下記コードの"urls"には、Getプロトコルにてデータ取得したいURLが記述してあります。
取得対象のURLは全部で900前後を予定していて、試しに取得数を100くらいまでに減らすと問題なくデータを取得できます。

コード

javascript

1urls = [ 2 "https://hoge/1", 3 "https://hoge/2", 4 ... 5 "https://hoge/900", 6] 7 8async getData() { 9 const res = await axios.all( 10 urls.map((url) => { 11 const res = axios.get(url) 12 return res 13 }) 14 ) 15 return res.data 16} 17 18export async function getStaticProps() { 19 const result = await getData(); 20 return { props: { data: result } }; 21} 22

実行環境

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuhiro_ikeda

2023/01/05 00:39

関係ないかもで備考ですが、本コードはNext.jsのgetStaticPropsにて動作してます故、npm run build時に動作しております。
int32_t

2023/01/05 00:56

urls 中の <ドメイン名> が間違っているということはありませんか?
think49

2023/01/05 11:35

> 取得対象のURLは全部で900前後を予定していて、試しに取得数を100くらいまでに減らすと問題なくデータを取得できます。 900前後あるURLは100個単位に分割して、9回リクエストした場合、すべてのデータを取得できるのでしょうか。
guest

回答1

0

ベストアンサー

なんとも言えませんが、要求量というよりはurlがおかしい箇所があったりするのでは?
fetchでテストする限り1000個くらいなげてもPromiseには特に問題はなさそうです。
(自前サーバーでなければスパム攻撃とみなされそうな気がしますが)
sample.php

PHP

1<?PHP 2print "res".$_GET["x"];

javascript

1window.addEventListener('DOMContentLoaded', ()=>{ 2 const n=1000; 3 const url="sample.php"; 4 const urls=Array(n).fill(null).map((_,x)=>`${url}?x=${x}`); 5 Promise.all(urls.map(x=>fetch(x).then(res=>res.text()))).then(res=>{ 6 console.log(res); 7 }); 8});

(参考)error処理

わざとエラーを返すsample2.php

PHP

1<?PHP 2if($_GET["x"]=="3"){ 3header('HTTP/1.1 403 Forbidden'); 4 exit; 5} 6if($_GET["x"]=="5"){ 7header('HTTP/1.1 500 Internal Server Error'); 8exit; 9} 10print "res".$_GET["x"];

(1)エラーを無視

javascript

1window.addEventListener('DOMContentLoaded', ()=>{ 2 const n=10; 3 const url="sample2.php"; 4 const urls=Array(n).fill(null).map((_,x)=>`${url}?x=${x}`); 5 Promise.all(urls.map(x=>fetch(x).then(res=>res.text()))).then(res=>{ 6 console.log(res); 7 }); 8});

(2)エラーを含むデータを取得

javascript

1window.addEventListener('DOMContentLoaded', ()=>{ 2 const n=10; 3 const url="sample2.php"; 4 const urls=Array(n).fill(null).map((_,x)=>`${url}?x=${x}`); 5 Promise.all(urls.map(x=>fetch(x).then(res=>{ 6 if(res.ok) return res.text(); 7 throw new Error(res.status); 8 }).catch(err=>err))).then(res=>{ 9 console.log(res); 10 }); 11});

(3)エラーを取得したら止める

javascript

1window.addEventListener('DOMContentLoaded', ()=>{ 2 const n=10; 3 const url="sample2.php"; 4 const urls=Array(n).fill(null).map((_,x)=>`${url}?x=${x}`); 5 Promise.all(urls.map(x=>fetch(x).then(res=>{ 6 if(res.ok) return res.text(); 7 throw new Error(res.status); 8 }))).then(res=>{ 9 console.log(res); 10 }).catch(err=>{ 11 console.log(err); 12 }); 13});

投稿2023/01/05 01:06

編集2023/01/05 01:31
yambejp

総合スコア114837

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuhiro_ikeda

2023/01/06 00:51

>なんとも言えませんが、要求量というよりはurlがおかしい箇所があったりするのでは? >fetchでテストする限り1000個くらいなげてもPromiseには特に問題はなさそうです。 ご確認ありがとうございます。 > (自前サーバーでなければスパム攻撃とみなされそうな気がしますが) こちらな気がしてきました。 どのAPIにアクセスしてるかというとpokeAPI※でして、以下ドキュメントを見ているとリクエストの制限がありそうです(a dairy rate limit of 300 requests per resource per IP address...) https://pokeapi.api-docs.io/v2.0/intro/nJa4jkWuFLPX3PWiD ※すみません、最初に補足で記述すべきでしたね
kazuhiro_ikeda

2023/01/06 00:58

> 以下ドキュメントを見ているとリクエストの制限がありそうです(a dairy rate limit of 300 requests per resource per IP address...) とはいえ今回の私の実装では、一つのリソースに対して何回もアクセスするのではなく、一度に複数のリソースに対してアクセスする といったものですので、なぜ取得できなかったのか?まだ分かってません。 ただ、ご指摘の通り1000近くのリクエストを投げるのはよろしくないでしょうし、該当APIにはGraphAPIも用意されていることがわかりましたので、こちらも使用を検討しようと思います。 ・promise.allの実装には問題なさそう ・リクエストを送る先のAPIを変更する ということで、本質問はクローズとさせていただきます。 ご回答ありがとうございました。
yambejp

2023/01/06 01:01

同一IPアドレスから一日300回までしか受け付けないとすると、900回で失敗した後100回なげたら通るというのはちょっと解せないですが、間隔をあければ300回以上うけつけてくれるなら、うまくコントロールすれば実現できるかもしれませんね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問