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

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

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

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

非同期処理

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

Ajax

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

Q&A

解決済

1回答

1938閲覧

【JavaScript】非同期制御が出来ない

ryozn

総合スコア7

JavaScript

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

非同期処理

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

Ajax

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

0グッド

0クリップ

投稿2015/09/16 13:07

B.jsにおいてはajaxの非同期制御は可能ですが、A.jsからB.jsを呼び出した際ににA. jsで非同期制御が出来ない状態です。
(doneの箇所にB.jsの実行が完了する前に到達してしまう。)

when~doneの記載方法に問題があるのか不明な状況です。
対応方法についてご教示頂きたいです。

A.js
function test(){
$.when(
test.search.textSearch('test', 1, null, null, null)
).done(function(data_a) {
return data_a;
});
}

B.js
test.search = (function() {
// テキスト検索
var textSearch = function(search, pageNo, treeNo, id, column) {
params = {"search": search,
"pageNo": pageNo,
"treeNo":treeNo,
"id":id
};
$.ajax({
type: "POST",
url: 'search/testSearch',
data: params,
dataType: 'jsonp',
jsonpCallback: 'callback',
}).done(function(json){
if(json.data && json.data.length ! = 0) {
return json.data;
}
});
};

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

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

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

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

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

guest

回答1

0

ベストアンサー

B.jsの下の部分が切れているようですので、その部分で何かしらしているのかもしれませんが、提示されている状態で終了だとすると、そもそもtest.searchがundefinedなので、test.search.textSearch('test', 1, null, null, null) でエラー起こしていませんか?

test.search.textSearchで実行させたいならB.jsは下記のような感じになるかと思います。

javascript

1test.search = (function() { 2 return { 3 // テキスト検索 4 textSearch: function(search, pageNo, treeNo, id, column) { 5 params = { 6 "search": search, 7 "pageNo": pageNo, 8 "treeNo":treeNo, 9 "id":id 10 }; 11 $.ajax({ 12 type: "POST", 13 url: 'data.json', 14 data: params, 15 dataType: 'json', 16 jsonpCallback: 'callback', 17 }) 18 .done(function(json){ 19 if(json.data && json.data.length !== 0) { 20 return json.data; 21 } 22 }); 23 } 24 }; 25})();

jQuery.when

jQuery.when()

jQuery.when( deferreds )
deferreds
Type: Deferred
One or more Deferred objects, or plain JavaScript objects.

公式ドキュメントではこのようになっています。
また、こちらの例 jQuery.DeferredとかjQuery.whenの使い方について ではjQuery.whenは下記のようになっています

javascript

1var hoge = $.ajax({ 2 url : "~" ,//{"text" : "hoge"}を返すAPIとする 3 type : "GET", 4 dataType : "json" 5}); 6 7var fuga = $.ajax({ 8 url : "~" ,//{"text" : "fuga"}を返すAPIとする 9 type : "GET", 10 dataType : "json" 11}); 12 13$.when(hoge, fuga).done(function(data1, data2){ 14 console.log(data1[0].text); //hoge 15 console.log(data2[0].text); //fuga 16});

その上で実行しようとしていた関数test.search.textSearchを見てみると、普通のfunctionですので、A.jsの$.when()内で呼び出したtest.search.textSearchがundefinedを返して終了した段階で、done()が実行されます。
$.when()内で呼び出した関数のAjaxの処理が完了してからdone()に進めたい場合は、呼び出す関数がDeferred objectsを返すようにしなければダメかと思います。
問題のコードの場合は $.ajax()をreturnしてしまえば良いかと思います。

javascript

1// B.js 2test.search = (function() { 3 return { 4 // テキスト検索 5 textSearch: function(search, pageNo, treeNo, id, column) { 6 params = { 7 "search": search, 8 "pageNo": pageNo, 9 "treeNo":treeNo, 10 "id":id 11 }; 12 // ajaxをreturnする 13 return $.ajax({ 14 type: "POST", 15 url: 'data.json', 16 data: params, 17 dataType: 'json', 18 jsonpCallback: 'callback', 19 }) 20 .done(function(json){ 21 if(json.data && json.data.length !== 0) { 22 return json.data; 23 } 24 }); 25 } 26 }; 27})();

※ ただし、ajaxを返す方法だとB.jsのajax完了時に恐らくdeferred.resolveが自動的に実行されるのでしょう。A.jsのdone()で受け取れる引数data_aは returnで指定されたjson.data ではなくjson になります。

jQuery.when().done()に加工した引数を渡したい場合

Ajaxで取得した値を加工して渡したい場合はtest.search.textSearchはdeferred.promise()を返して、deferred.resolve()を使って引数を渡すようにする必要があるかと思います。

javascript

1// B.js 2test.search = (function() { 3 return { 4 // テキスト検索 5 textSearch: function(search, pageNo, treeNo, id, column) { 6 params = { 7 "search": search, 8 "pageNo": pageNo, 9 "treeNo":treeNo, 10 "id":id 11 }; 12 var defer = $.Deferred(); 13 $.ajax({ 14 type: "POST", 15 url: 'data.json', 16 data: params, 17 dataType: 'json', 18 jsonpCallback: 'callback', 19 }) 20 .done(function(json){ 21 if(json.data && json.data.length !== 0) { 22 // defer.resolve を使ってA.jsのdone()に引数を渡す 23 defer.resolve( json.data ); 24 } 25 }); 26 // defer.promiseを返す 27 return defer.promise(this); 28 } 29 }; 30})();

jQuery.when()を使わなくても良いかも。

こうするとtest.search.textSearch()はDeferred Objectを返しちゃっているので、A.jsで複数の非同期書処理を行いたいのでなければ、jQuery.whenを使わずに単純に下記のように書いてしまってもOKです。

javascript

1// A.js 2function test(){ 3 test.search.textSearch('test', 1, null, null, null) 4 .done(function(data_a) { 5 return data_a; 6 }); 7}

投稿2015/09/16 18:28

編集2015/09/16 18:42
KiKiKi_KiKi

総合スコア596

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

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

ryozn

2015/09/17 12:15

分かり易い回答ありがとうございました。 会社で確認後、実際に試したところ動作出来ました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問