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

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

新規登録して質問してみよう
ただいま回答率
85.50%
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

解決済

3回答

2614閲覧

Ajaxが順序通り実行できない

shaketonori

総合スコア22

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クリップ

投稿2018/05/28 05:36

連続した ajax を順番通り実行するために、これまで「async:false」で同期させていましたが、
「async:false」は非推奨になったということで警告が出てくるため、書き直しているところです。

いろいろ調べてみると、promiseオブジェクトのステータスを監視することによって、同期的処理ができる
ということで以下のコードを書きました。

1番目の ajax では分類検索を行い、categoryText に結果("bird" 又は "fish")を表示します。
その表示された結果に基づいて2番目の ajax が起動し、該当する「名前」を2つ目の nameText
に表示("swallow" 又は "carp")するとというものです。

コンソールの結果を見てみると、2つの ajax の順序が逆になるというより、1つの ajax 内で
も前後しているようです。

ステータス1-1
ステータス1-2
ステータス2-1
ステータス2-2
の順番で処理してもらいたいのですが・・・

Deferred や then の扱い方が正しく理解できていないようです。

どなたかご指導くださるよう、お願い致します。

<!DOCTYPE HTML> <html lang ="ja"> <head> <meta charset ="utf-8"> <title>テスト</title> <script type="text/javascript" src="../js/jquery-1.11.2.min.js"></script> <script type="text/javascript"> function func1(){ var number = $('#numberText').val(); var dfd1 = $.Deferred(); $.ajax({ type: "POST", url: "../code/backyard/SearchCategory.php", data: {"number":number}, dataType: 'text', }).done(function(response) { $('#categoryText').get(0).value = response; dfd1.resolve(); }).fail(function(response) { alert('error!!!'); }).always(function() { console.log("func1 complete"); console.log('ステータス1-1================' + dfd1.state()); }); console.log('ステータス1-2================' + dfd1.state()); return dfd1.promise(); } function func2(){ var category = $('#categoryText').val(); console.log("category=========" + category); var dfd2 = $.Deferred(); $.ajax({ type: "POST", url: "../code/backyard/SearchObject.php", data: {"category":category}, dataType: 'text', }).done(function(response) { $('#nameText').get(0).value = response; dfd2.resolve(); }).fail(function(response) { alert('error!!!'); }).always(function() { console.log("func2 complete"); console.log('ステータス2-1================' + dfd2.state()); }); console.log('ステータス2-2================' + dfd2.state()); return dfd2.promise(); } function goSearch(){ func1() .then(func2()); } </script> </head> <body> 番号<input type="text" id="numberText" /> <input type="button" value="送信" onclick="goSearch()" /> <br /> 種類<input type="text" id="categoryText" /><br /> 名前<input type="text" id="nameText" /> </div> </body>

【コンソールの表示内容】
ステータス1-2================pending
category=========
ステータス2-2================pending
func2 complete
ステータス2-1================resolved
func1 complete
ステータス1-1================resolved

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

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

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

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

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

guest

回答3

0

ベストアンサー

これだけで解消するかはわからないですが、.thenで待たせるためには、引数を関数にする必要があります。then(func2());のように書いてしまうと、「func2を実行してからその結果を.thenに渡す」という意味になり、意図したように動きません。

javascript

1 function goSearch(){ 2 func1().then(function(){ 3 func2(); 4 }); 5 }

投稿2018/05/28 05:46

maisumakun

総合スコア145121

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

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

shaketonori

2018/05/28 22:06

回答ありがとうございました。 質問をして、わずか10分後の回答には驚きました。 自己解決しようと、その後いろいろ試みたのですがうまくいきませんでした。 maisumakunさんに教えて頂いたとおりのコードで func1 → func2 の順で処理 できることがわかりました。 ただ、コンソールの表示内容は以下の感じで、 1-1 1-2 2-1 2-2 とならず、先に「category=========bird」が表示されるなど、イマイチすっきり しないのですが、これが非同期処理なんだろうな、と納得した次第です。 【コンソールの表示内容】 ステータス1-2================pending category=========bird ステータス2-2================pending func1 complete ステータス1-1================resolved func2 complete ステータス2-1================resolved maisumakunさんに教えて頂いたコードを参考に、以下のように変形して使用するつもりです。 function goSearch(){ var promise1 = func1(); var promiseThen = promise1.then(func2); promiseThen.done(function(result){ console.log("すべて完了しました"); }); } 素早く的確な回答。 本当にどうもありがとうございました。
guest

0

ちょっと認識が違うのかもしれませんが、非同期でうけとったあとソートして表示すればいいのでは?

  • hoge.php

PHP

1$(function(){ 2 var datas=[]; 3 $.when( 4 $.ajax({url:"fuga.php",data:{id:1}}).done(function(d1){datas.push({sort:1,data:d1});}), 5 $.ajax({url:"fuga.php",data:{id:2}}).done(function(d2){datas.push({sort:2,data:d2});}), 6 $.ajax({url:"fuga.php",data:{id:3}}).done(function(d3){datas.push({sort:3,data:d3});}) 7 ).done(function(){ 8 datas.sort(function(x,y){ 9 return x.sort>y.sort?1:-1; 10 }).forEach(function(x){ 11 console.log(x.data); 12 }); 13 }); 14});
  • fuga.php

PHP

1<?PHP 2$id=filter_input(INPUT_GET,"id"); 3if($id==1) sleep(2); 4if($id==3) sleep(1); 5print "data".$id; 6?>

投稿2018/05/28 07:40

yambejp

総合スコア114583

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

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

shaketonori

2018/05/28 22:04

回答ありがとうございました。 ただ、申し訳ないのですが、回答の「非同期でうけとったあとソートして表示すれば」の 意味が全く分かりませんでした。 もう少しかみ砕いてご説明して頂けると助かります。
yambejp

2018/05/29 00:21

>もう少しかみ砕いて うーん、サンプルもつけているのでこれ以上無いと思うのですが 受け取る順番がわからないないなら、とりあえず全部受け取って データが揃ってから想定した順番で表示すればいいということ 例で言えば、データは2→3→1の順番で受け取りますが、 予めソート順を1→2→3のように指定してあるので、表示もそのようになります。 ちなみにfunc1がおわってからfunc2を実行するのは直列処理なので 時間の無駄が発生するのでやめたほうがいいです
guest

0

提示のコードだとfunc1とfunc2を分けている意味があまりないような…
func1の$.ajax().doneのコールバック内でfunc2の中身を実行すればいいのでは?

投稿2018/05/28 08:33

sousuke

総合スコア3828

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

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

shaketonori

2018/05/28 22:03

回答ありがとうございました。 確かにコールバック内に func2 の中身を書けば実現するのですが、ajax が入れ子になって 可読性が悪くなってしまうため、ajaxを外出しにしたかったのです。 また、外出しにすれば他からも使い回しできますので。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問