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

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

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

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

2回答

1857閲覧

ajax逐次処理でエラーが出た場合にrejectさせてループから抜けたい

defeatist

総合スコア35

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

1クリップ

投稿2019/05/26 13:38

前提・実現したいこと

javascript(jquery)にて、あるまとまった非同期処理を実行させ、全ての処理が成功すればresolveさせ、途中でうまくいかなければ、その時にrejectさせ、後続の処理をさせないようにしたいです。

発生している問題・エラーメッセージ

ajax処理がうまくいかなかった場合の処理をイテレータの回数分実行した後rejectされてしまう。

該当のソースコード

javascript

1let func = function(){ 2 return new Promise(function (resolve, reject){ 3 for(let i = 0; i < 10; i++){ 4 $.ajax({ 5 url: 'http://', 6 type:'Get' 7 }).done(function(response, status, jqXHR) { 8 console.log("成功"); 9 }).fail(function(jqXHR, status, error) { 10 console.log("エラー"); 11 reject("rejectされました"); 12 }); 13 } 14 resolve(); 15 }); 16} 17 18func().then(function(){ 19 console.log("終了"); 20}) 21.catch(function (error) { 22 console.log(error); 23});

試したこと

returnを記述する

javascript

1let func = function(){ 2 return new Promise(function (resolve, reject){ 3 for(let i = 0; i < 10; i++){ 4 $.ajax({ 5 url: 'https://', 6 type:'Get' 7 }).done(function(response, status, jqXHR) { 8 console.log("成功"); 9 }).fail(function(jqXHR, status, error) { 10 console.log("エラー"); 11 reject("rejectされました"); 12 return; 13 }); 14 } 15 resolve(); 16 }); 17} 18 19func().then(function(){ 20 console.log("終了"); 21}) 22.catch(function (error) { 23 console.log(error); 24});
  • 結果

変化なし

breakを記述する

javascript

1let func = function(){ 2 return new Promise(function (resolve, reject){ 3 for(let i = 0; i < 10; i++){ 4 $.ajax({ 5 url: 'https://', 6 type:'Get' 7 }).done(function(response, status, jqXHR) { 8 console.log("成功"); 9 }).fail(function(jqXHR, status, error) { 10 console.log("エラー"); 11 reject("rejectされました"); 12 break; 13 }); 14 } 15 resolve(); 16 }); 17} 18 19func().then(function(){ 20 console.log("終了"); 21}) 22.catch(function (error) { 23 console.log(error); 24});
  • 結果

SyntaxError: Illegal break statementというエラーが発生

補足情報(FW/ツールのバージョンなど)

jquery(3.4.1)

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

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

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

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

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

guest

回答2

0

こんにちは

複数の非同期処理を実行させ、それらの全てが成功したときに resolve されて何らかの処理を後続の.then で行うような Promise を作りたいときは、Promise.all() が便利です。この際に、まとめる対象となる個々の非同期処理もPromiseにします。

以下、簡単なサンプルを挙げます。

以下は、HTTPリクエストを $.ajax で送信するPromiseを複数作り、それらのすべてが成功したときに、後続の .then に設定した関数に処理をつなげるために、Promise.all() を使った簡単なサンプルです。

javascript

1const getter = (name, url) => new Promise(function(resolve, reject) { 2 3 $.ajax({ 4 url, 5 type:'get' 6 }).done(function(response, status, jqXHR) { 7 console.log(`成功: ${name}`); 8 resolve(response.result); 9 }).fail(function(jqXHR, status, error) { 10 console.log(`エラー: ${name}`); 11 reject({ name, status: jqXHR.status}); 12 }); 13 14}); 15 16 17const getters = [ 18 getter('foo', 'https://demo2746340.mockable.io/q191495/0.json'), 19 getter('bar', 'https://demo2746340.mockable.io/q191495/1.json'), 20 getter('baz', 'https://demo2746340.mockable.io/q191495/2.json'), 21]; 22 23Promise.all(getters) 24 .then(results => { 25 console.log(results); 26 }) 27 .catch(error => { 28 console.log(error); 29 }); 30

上記で、https://demo2746340から始まる各URLをGETすると、HTTPステータス200で、以下

json

1{ "result": 1000 }

のような形の簡単なJSONを返します。

上記のコードを動作確認するために 以下のjsFidle に上げています。

Console に以下のように

成功: foo 成功: bar 成功: baz

表示されており(※順番は異なるかもしれませんが)、各々のリクエストが成功で返っており、かつ、 Promise.all で作られた Promise の then に渡された関数が実行されて、console.log(results); により

[1000, 1001, 1002]

と表示されることが分かると思います。

次にどれか1つでも失敗する場合の例です。上記のコードで、 getters の2番目のURLの末尾を 3.json に変えます。

javascript

1const getters = [ 2 getter('foo', 'https://demo2746340.mockable.io/q191495/0.json'), 3 getter('bar', 'https://demo2746340.mockable.io/q191495/3.json'), 4 getter('baz', 'https://demo2746340.mockable.io/q191495/2.json'), 5];

https://demo2746340.mockable.io/q191495/3.json はステータス 404 を返すようにしています。以下で動作確認できます。

上記では、 Promise.all で作られたPromise に catch で設定された関数が実行されて、以下のように表示されると思います。(※順番は異なるかもしれません)

成功: foo エラー: bar Object {name="bar", status=404} 成功: baz

以上、拙いサンプルですが、ご質問にある、

あるまとまった非同期処理を実行させ、全ての処理が成功すればresolveさせ

たい場合は、 Promise.all() を使うことをお勧めするのがこの回答の主旨となります。

参考になれば幸いです。

投稿2019/05/26 16:39

編集2019/05/27 05:06
jun68ykt

総合スコア9058

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

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

defeatist

2019/05/27 06:54

ありがとうございます
guest

0

ベストアンサー

考え方が2つあります。

仮にsend先をこうしておきます

  • send.php

仕様:引数dataが1か3のときはエラーを返す、成功時は5秒待ってから出力

PHP

1<?PHP 2$data=filter_input(INPUT_GET,"data"); 3if(in_array($data,[1,3])){ 4header('HTTP/1.1 404 Not Found'); 5 print "incorrect"; 6 exit; 7} 8sleep(5); // 5秒待つ 9print "success";
  • 失敗を得ても「errorだった」という成功に流す

この場合失敗したとわかっていても成功処理を5秒まってから出力される

javascript

1const func=()=>{ 2 var d=[]; 3 for(let i = 0; i < 5; i++){ 4 d[i]=$.Deferred(); 5 $.ajax({ 6 url: 'send.php', 7 type:'GET', 8 data:{data:i}, 9 }).done(data=>{ 10 d[i].resolve(data); 11 }).fail((xhr,err)=>{ 12 d[i].resolve(err); //失敗でもresolveする 13 }); 14 } 15 return $.when.apply(null,d).done((...data)=>{ 16 return data; 17 }); 18}; 19 20func().then((...data)=>{ 21 console.log(data); 22}).fail(function(err){ 23 console.log(err); 24});

※これならfailに流れないのでエラー状況を把握することができます。

  • ちゃんとrejectする

この場合、成功処理の5秒は待たずにerrorになった瞬間にエラーがわかる

javascript

1const func=()=>{ 2 var d=[]; 3 for(let i = 0; i < 5; i++){ 4 d[i]=$.Deferred(); 5 $.ajax({ 6 url: 'send.php', 7 type:'GET', 8 data:{data:i}, 9 }).done(data=>{ 10 d[i].resolve(data); 11 }).fail((xhr,err)=>{ 12 d[i].reject(error);// ちゃんとリジェクトすると 13 }); 14 } 15 return $.when.apply(null,d).done((...data)=>{ 16 return data; 17 }); 18}; 19 20func().then((...data)=>{ 21 console.log(data); 22}).fail(function(err){ 23 console.log(err); // failに流れるので確認できるのはrejectした引数 24});

投稿2019/05/27 03:35

編集2019/05/27 03:41
yambejp

総合スコア114810

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

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

yambejp

2019/05/27 03:44

jQueryで処理する限りpromiseを利用するより$.Deferredの方が 処理が楽だと思います
defeatist

2019/05/27 06:23

ありがとうございます 本題とは、ずれてしまうのですが、 return $.when.apply(null,d).done((...data)=>{ return data; }); ではなく return $.when(...d).done((...data)=>{ return data; }) ではだめなのでしょうか?
yambejp

2019/05/27 06:25

大丈夫ですよ その方がよりES6っぽいですね
defeatist

2019/05/27 06:54

すみません 自分で逐次処理と言っていたことを忘れていました ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問