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

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

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

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

JavaScript

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

Ajax

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

Q&A

解決済

1回答

1311閲覧

javascriptクラスのメンバ変数の挙動について

TakeruYamamura

総合スコア7

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

JavaScript

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

Ajax

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

0グッド

0クリップ

投稿2020/10/25 11:20

編集2020/10/29 12:28

前提・実現したいこと

商品の在庫状況を判定する機能をjavascriptで開発しております。
ajaxで在庫検索APIに接続し、取得した結果(JSON)をクラスで定義したメンバ変数(配列)に渡し、クラス内の別の関数で使用したいのですが、うまく動きません。
以下、事象の詳細です。

①クラス内でメンバ変数(配列)を定義
②ajaxでAPIに接続し在庫状況を検索する関数を使用し、在庫状況をメンバ変数に格納
③②の関数の内と外で配列の挙動が異なる ← 問題

上記の②の関数内ではJSONの連想配列として動いてくれるのですが、関数の外では配列にはなっている(chromeのコンソール上にはArrayと表示されている)ものの、要素を指定して値を参照することができない状態となってしまっています。

上記関数の外でも値を参照して抽出するためにはどのように修正すればよろしいでしょうか。
ご教授のほど、よろしくお願いいたします。

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

chromeのコンソール上の表示内容です。(console.logで出力させたもの)

こっちがだめなやつ [] JSONの連想配列の要素たち length: 37 __proto__: Array(0) ほんとはこっちになってほしい (37) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] JSONの連想配列の要素たち length: 37 __proto__: Array(0)

該当のソースコード

javascript

1this.Search_Product_API = function(param_nomal, product_type_str){ 2 // 親クラスのインスタンスを生成 3 var oya_class = this; 4 5 // APIで通常商品の在庫状況を検索しリストに格納 6 return new Promise(function(resolve, reject){ 7 $.ajax({ 8 url: 'APIのURL', 9 data: param_nomal, 10 dataType: 'jsonp', 11 success: function(data){ 12 // 検索結果をリストに格納 13 for (var i = 0; i < data.length; i++) { 14 // 検索結果を変数に格納 15 var shohin_cd = data[i].shohin_cd; 16 var zaiko_kbn = data[i].zaiko_kbn; 17 18 // 検索結果をjsonに格納 19 var result_json = { 20 "shohin_cd": shohin_cd, 21 "zaiko_kbn": zaiko_kbn 22 } 23 24 if(product_type_str == 'nomal'){ 25 // 検索結果を格納したjsonをリストに追加 26 oya_class.nomal_zaiko_list.push(result_json); 27 }else if(product_type_str == 'campaign'){ 28 // 検索結果を格納したjsonをリストに追加 29 oya_class.campaign_zaiko_list.push(result_json); 30 } 31 32 } 33           console.log(oya_class.campaign_zaiko_list); ← ここは問題ない 34 } 35 }) 36       console.log(oya_class.campaign_zaiko_list); ← ここでリストが空 37 }) 38 } 39 40

試したこと

配列をJSON文字列にパース→JSON型にパースを試しましたが、JSON文字列にパースからできない状態でした。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

gentaro

2020/10/25 13:26

うまくいかないのはよくわかったけど、質問内容は何なんだろう。 原因が知りたいのか、意図している動作にするためにはどう修正するべきなのかを知りたいのか。 ここを読んでる人はエスパーじゃないので、あなたが述べないと意図が伝わりません。 ちゃんと質問形式にしましょう。
TakeruYamamura

2020/10/25 13:32

申し訳ありません。 質問内容を修正させていただきました。 意図している動作にするための修正方法をお聞きしたかった次第です。 ご指摘ありがとうございました。
guest

回答1

0

ベストアンサー

非同期で取得しようとしてるのに(ajax)、同期的に使用しようとしてるからです。
つまり、ajaxは基本非同期なので、
その次行以降の処理は先に走ってしまうので、変数の中身が入る前に使おうとしてしまっているので、空になるわけです。
取得内容が必要な処理は、
非同期処理が完了した後に、取得内容を使う処理をするようにしましょう。

Promiseや、fetchを上手く使うなどでやるといいかと。

投稿2020/10/25 14:06

miyabi_takatsuk

総合スコア9555

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

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

TakeruYamamura

2020/10/25 15:15

ご教授ありがとうございます。 ajaxでAPIへの接続を実現している関数(product_search_api)で、async:falseとしているのですが、これでは同期処理にはならないのでしょうか。。。? .doneを使用していると勝手に非同期処理ということでしょうか。。。?
TakeruYamamura

2020/10/25 15:36

async/awaitを使用することで問題解決いたしました。 ご教授くださりありがとうございました。
miyabi_takatsuk

2020/10/26 00:49

ajax処理自体をasync: falseにするのはあまりよろしくありません。 (Chromeで警告が出ます) また、doneの内側の処理で実行したものを同期的にしても、 jQueryのajax処理自体が、全体の処理を同期的にする仕様ではありません。 (同スコープ上の処理でしか同期的にならない。今回は内側に潜った先で同期的になっているが、外側スコープには関係ない→console.log時点ではdoneと同スコープのため、その非同期処理が優先になる) なので、awaitをうまく使うで解決ですね。 よかったです。
TakeruYamamura

2020/10/26 10:35

なるほどです。 今回の場合は、ajaxの処理自体は同期的になっているが、「product_search_api」は同期的になっていないので、APIへ接続し情報を取得する前に次の処理に進んでしまっていると理解しました。 ご丁寧にありがとうございました。 大変助かりました。
miyabi_takatsuk

2020/10/26 17:26

そうです、その挙動になっていたで間違いないです。 解決とご理解いただけてよかったです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問