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

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

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

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

Q&A

解決済

1回答

1907閲覧

JavaScript(JQuery):AjaxでDBからデータ取得する操作をユーザが立て続けに操作した場合、順次処理を保ちたい

saya24

総合スコア222

JavaScript

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

0グッド

2クリップ

投稿2019/01/22 11:10

A処理:
INPUT type=textの要素のvalue値で、DBから当該枠に入力された取引先コードの名称を取得して
別のINPUT type=textの要素(ReadOnly)にその名称を収める処理です。
dcdinfogetというFUNCTIONを、取引先コード枠の内容変化を察知して呼び出すようなつくりです。

B処理:
ラジオボタンの変化察知で、上記で画面表示された取引先名称を始めとした複数のINPUT type=textの内容から関連する実績データをDBから取得またTableへ明細生成する処理です。

【質問】
A処理もB処理も、ユーザ操作をトリガとした作りになっていますが、『A処理・B処理が立て続けに行われた際』にA処理の完了を待たずしてB処理が行われる傾向にあります。
B処理の引数をA処理で生成しているわけですから、A処理が確実に完了するまでB処理の内部動作を保留にしたい、というのが願いです。
こういった場合、どういう解決策をとるのが一般的なのでしょうか?
B処理の中で、A処理で呼び出されているFUNCTIONを無条件に呼び出すことに問題はありません。

【悩ましいところ】
B処理は既にDeferredなる技術を採用し、DB参照用途のFUNCTIONを呼ぶようにしています。
DBから実績データを得る上で、真っ先に画面をモーダル化・全体を覆う透過DIVを表して、このFUNCTIONのDONEで当該の透過DIVを消す、Tableをあらわにする流れです。

当方はDefferredを入れ子にしたことがありません。やはり入れ子にすべき、とするとどういった記述をするのでしょうか?
それとも、ただ単にhiddenの要素をA処理の利用中・利用完了状態を表す項目として使い、B処理の中でこれをミリ秒単位/ループで確認するのが常套手段なのでしょうか?

A処理

JQuery

1$("#dcd").on("change",function() { 2 dcdinfoGet($(this)); 3});

B処理

JQuery

1function updRenew () { 2 updRemove(); 3 // モーダルモードにするため画面を覆う 4 $("body").append('<div id="modal-overlay"></div>') ; 5 $("#modal-overlay").append("<img id='loader' src='./img/ajax-loader.gif' alt='Now Loading...'>"); 6 $("#modal-overlay").fadeIn("slow"); 7 var d = mcrsvinq(); 8 d.done(function(){ 9 $("#loader").remove(); 10 $("#modal-overlay").fadeOut("slow", function(){ 11 $('#modal-overlay').remove(); 12 }); 13 }); 14 d.fail(function(){ 15 $("#modal-overlay").fadeOut("slow", function(){ 16 $('#modal-overlay').remove(); 17 }); 18 alert("【基幹システムから予約情報を参照できず...】"); 19 return false; 20 }); 21}

ご見解を頂けましたら幸です、ヒントだけでも!

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

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

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

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

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

wwbQzhMkhhgEmhU

2019/01/22 15:20

通りすがりの意見です。ぶっちゃけどれでもいいよと思ってしまいますが、 すでに気付かれているとおり、 (1)Bの中でAの処理も入れる (2)Deferredを入れ子にする(?) か、ユーザビリティを犠牲にして、 (3)Aが終わるまでBを発火させない(disableにする) かだと思います。統一的に出来て文句が出そうになければ(2)、文句言いそうな人が多そうなら(1)、決まらなかったら(3)にしちゃうぞと言って脅す、くらいかなぁ。 なお、参考意見なので回答ではありません。
saya24

2019/01/23 01:52

wwbQzhMkhhgEmhU さん、ありがとうございます。 周囲に全く聞ける人間がいないので、(3)の解決策があることを思い付きませんでしたよ。 助かりました。
guest

回答1

0

ベストアンサー

現状のコードの流れをぶった切ってゼロベースで正解を提示しても良いという前提ならば、
ReactやVue.js、Angular等のJSフレームワーク使えが最善手です。

jQueryはDOM操作に特化したライブラリです。
JavaScript世界に残っている変数等の状態とどう付き合っていくか、
この二重管理の煩わしさが一生つきまといます。

JSフレームワークはJS世界のデータが常に正、
テンプレートHTMLを読み込ませて、データが書き換わったのを察知してテンプレートHTMLを元に在るべき姿にDOMが勝手に書き換わります。
もちろんパフォーマンスは最低限の差分更新されるので、緻密な差分計算をしたJS上級者が操るDOM操作ならいざしらず、素人が下手にjQueryのhtml()で弄るより圧倒的に速いです。

こういった場合、どういう解決策をとるのが一般的なのでしょうか?

質問文をざっくり読んでの感想ですが、
B処理はA処理に依存していますよね?

A処理発火されAjaxで新しいデータを取得しにいったということは。
現在画面へ出せるデータが存在しない事を意味します。
捨てられる予定の旧データをB処理でこねくり回しても「お前何やってんの?」状態なわけですよ。

なのでA処理が実行された瞬間、
せめてB処理のトリガーであるラジオボタンを非活性(readonly, disabled, display: none;などなど)にするのが一般的だと思います。
整合性を取るならデータを捨てたという扱いで画面を一掃してみてはどうでしょうか?


もしB処理に使われるラジオボタンはあくまでレンダリング時に使われる参考値であり、
A処理の最中もカチャカチャ切り替える事が可能で、A処理完了時の画面出力でよしなに出力して欲しいのであれば、
こんな対応はいかがでしょうか?

JavaScriptは関数を実行したらスコープが作られます。
そのスコープ内で作られた変数というのは、中身が全て捨てられない限り残り続ける性質があります。
サンプルとしてはこんな感じ

JavaScript

1var counter = (function () { 2 var count = 0; 3 4 return function () { 5 count += 1; 6 return count; 7 } 8})(); 9 10console.log(counter()); // 1 11console.log(counter()); // 2 12console.log(counter()); // 3 13console.log(counter()); // 4 14console.log(counter()); // 5

counter関数を発火する度に数値が1個ずつ増えているのを確認出来ますが、
この時、関数内のcount変数は生き残り続けます。
なので、細部が分からないので適当ですが、こんな感じが良いんじゃないかな?

JavaScript

1$(function () { 2 // こんな風に変数を宣言しておいて使い倒す 3 var bSelected = null; 4 var data = null; 5 6 // A処理 7 $("#dcd").on("change",function() { 8 data = null; 9 // dcdinfoGetの中身は知らんけど、Ajaxを受け取った段階らdataに結果を代入する作りに作り変える 10 dcdinfoGet($(this)); 11 12 // ここの部分、updRenewの発火が必要な場所全てでコピペになるのがjQueryの限界、辛くなってきたらJSフレームワーク行け 13 if (bSelected === 'hoge') updRenew(); 14 }); 15 16 // B処理の発火をこんな感じにしてラッピングする 17 function updBSelected () { 18 bSelected = $('.radio-b').val(); 19 if (data) updRenew(); 20 } 21 22 function updRenew () { 23 // 割愛 24 } 25});

投稿2019/01/23 04:01

miyabi-sun

総合スコア21158

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

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

miyabi-sun

2019/01/23 04:02

色々書きましたが、ラジオボタンはモーダルボックスの表示を司ってるので、 素直にラジオボタンを非活性にするのが対応としては一番自然だろうと思います。
saya24

2019/01/23 10:18

miyabi-sun コードも交えご丁寧な説明ありがとうございました。JSにフレームワークが有ることさえ知りませんでした。カレンダやトースト、行列固定のTabl表示といった小手先のライブラリぐらいしか利用経験がないもので。いつかチャレンジしてみますね。 やはり、B処理のラジオボタンを非活性にしておくのが常套手段のようですね。大変価値のあるご見解、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問