🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

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

jQuery

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

Q&A

解決済

1回答

748閲覧

jQuery.Deferredと.then()を使った連続処理が実行されない

miyaken912

総合スコア15

JavaScript

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

jQuery

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

0グッド

2クリップ

投稿2019/10/20 15:34

編集2019/10/21 03:56

前提・実現したいこと

Jqueryでコンピュータと対戦するじゃんけんゲームを作っています。
あいこの場合は、もう一度対戦するようにしたいのですが、jQuery.Deferredと.then()を使った一連の処理が実行されず、無限ループになってしまいます。

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

ChromeのDeveloper toolで、show_result()のwhileループ処理から抜け出せず、以下のエラーメッセージが表示される。

Posed before potential memory crash

該当のソースコード

javascript

1function show_jankenpon(text) { 2 let d = new $.Deferred(); 3 $("#instruction") 4 .html(text) 5 .show() 6 .fadeOut(1000, function() { 7 d.resolve(); 8 }); 9 return d.promise(); 10} 11 12$(function() { 13 const Gu_0 = 0; 14 const Cho_1 = 1; 15 const Par_2 = 2; 16 let pc_hand; 17 let my_hand; 18 let result; 19 20 function reset() { 21 let d = new $.Deferred(); 22 23 my_hand = null; 24 pc_hand = null; 25 result = null; 26 $("#my_hand_id").html(""); 27 $("#pc_hand_id").html(""); 28 $("#instruction").html(""); 29 $("#judgement").html(""); 30 d.resolve(); 31 32 return d.promise(); 33 } 34 35 function pc_janken() { 36 let d = new $.Deferred(); 37 pc_hand = Math.floor(Math.random() * 3); 38 console.log("in pc_janken pc_hand= " + pc_hand); 39 if (pc_hand == Gu_0) { 40 $("#pc_hand_id") 41 .html("グー") 42 .fadeIn(2000, d.resolve()); 43 } else if (pc_hand == Cho_1) { 44 $("#pc_hand_id") 45 .html("チョキ") 46 .fadeIn(2000, d.resolve()); 47 } else if (pc_hand == Par_2) { 48 $("#pc_hand_id") 49 .html("パー") 50 .fadeIn(2000, d.resolve()); 51 } 52 return d.promise(); 53 } 54 55 function judge() { 56 let d = new $.Deferred(); 57 const Gu_0 = 0; 58 const Cho_1 = 1; 59 const Par_2 = 2; 60 61 if (my_hand == Gu_0 && pc_hand == Gu_0) { 62 result = "aiko"; 63 } 64 if (my_hand == Gu_0 && pc_hand == Cho_1) { 65 result = "you win"; 66 } 67 if (my_hand == Gu_0 && pc_hand == Par_2) { 68 result = "you lose"; 69 } 70 if (my_hand == Cho_1 && pc_hand == Gu_0) { 71 result = "you lose"; 72 } 73 if (my_hand == Cho_1 && pc_hand == Cho_1) { 74 result = "aiko"; 75 } 76 if (my_hand == Cho_1 && pc_hand == Par_2) { 77 result = "you win"; 78 } 79 if (my_hand == Par_2 && pc_hand == Gu_0) { 80 result = "you win"; 81 } 82 if (my_hand == Par_2 && pc_hand == Cho_1) { 83 result = "you lose"; 84 } 85 if (my_hand == Par_2 && pc_hand == Par_2) { 86 result = "aiko"; 87 } 88 if (my_hand == null) { 89 result = "atodashi"; 90 } 91 d.resolve(); 92 return d.promise(); 93 } 94 95 function show_aiko() { 96 let d = new $.Deferred(); 97 $("#judgement").html("あいこです"); 98 setTimeout(function() { 99 d.resolve(); 100 }, 1000); 101 return d.promise(); 102 } 103 104 function show_result() { 105 console.log(result); 106 while (result == "aiko") { 107 show_aiko() 108 .then(reset) 109 .then(show_jankenpon.bind(null, "あい")) 110 .then(show_jankenpon.bind(null, "こで")) 111 .then(show_jankenpon.bind(null, "しょ")) 112 .then(pc_janken) 113 .then(judge) 114 } 115 116 if (result == "you win") { 117 $("#judgement").html("あなたの勝ちです"); 118 } else if (result == "you lose") { 119 $("#judgement").html("あなたの負けです"); 120 } else if (result == "atodashi") { 121 $("#judgement").html("後出しであなたの負けです"); 122 } 123 } 124 125 $("#gu_btn").on("click", function() { 126 my_hand = Gu_0; 127 $("#my_hand_id").html("グー"); 128 console.log("Gu clicked"); 129 }); 130 $("#cho_btn").on("click", function() { 131 my_hand = Cho_1; 132 $("#my_hand_id").html("チョキ"); 133 console.log("Cho clicked"); 134 }); 135 $("#par_btn").on("click", function() { 136 my_hand = Par_2; 137 $("#my_hand_id").html("パー"); 138 console.log("Par clicked"); 139 }); 140 141 $("#start").on("click", function() { 142 reset() 143 .then(show_jankenpon.bind(null, "じゃん")) 144 .then(show_jankenpon.bind(null, "けん")) 145 .then(show_jankenpon.bind(null, "ぽん")) 146 .then(pc_janken) 147 .then(judge) 148 .then(show_result); 149 }); 150}); 151

HTML

1 2<!DOCTYPE html> 3<html> 4 <head> 5 <meta charset="utf-8" /> 6 <meta name="viewport" content="width=device-width" /> 7 <script src="js/jquery-2.1.3.min.js"></script> 8 <link rel="stylesheet" href="css/sample.css" /> 9 <title>じゃんけん</title> 10 </head> 11 <body> 12 <header> 13 <h1>じゃんけんゲーム</h1> 14 <button id="start">START</button> 15 <br /> 16 <br /> 17 </header> 18 19 <main> 20 <div id="instruction"></div> 21 <br /> 22 <div id="hands"> 23 <div>あなた 「<span id="my_hand_id"></span>」</div> 24 <div>コンピュータ 「<span id="pc_hand_id"></span>」</div> 25 </div> 26 <br /> 27 <div id="judgement"></div> 28 </main> 29 30 <div id="controller"> 31 <ul> 32 <li id="gu_btn">グー</li> 33 <li id="cho_btn">チョキ</li> 34 <li id="par_btn">パー</li> 35 </ul> 36 <button id="onsei_btn">音声入力</button> 37 </div> 38 39 <footer></footer> 40 <script src="js/main.js"></script> 41 </body> 42</html> 43

試したこと

ChoromeのDeveloper toolで見ると、show_result()のwhile文のところで無限ループになってしまっているようです。
show_aiko()以降の.then()が実行されず、resultが"aiko"のまま変わらないのが原因のようですが、なぜ実行されないのかわかりません。

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

初心者のため、質問に不十分な点があるかもしれませんが、どうぞ宜しくお願い致します。

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

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

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

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

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

yambejp

2019/10/21 00:23

なにをトリガーにどうじゃんけんするのでしょうか? HTMLも提示したほうが良いと思います
miyaken912

2019/10/21 03:56

HTMLを含め全体像を記載しました。 どうぞ宜しくお願い致します。
guest

回答1

0

ベストアンサー

非同期でもないないのでdeferredで処理しなければよいのでは?

sample

非同期になる要素がないのでdeferredを外したバージョンのsampleをあげておきます
ちょっと雑に書いたのでもうすこし調整が必要かも
(挙動が違うならご指摘ください)

javascript

1<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 2<script> 3$(function(){ 4 var count=0; 5 var my_hand=""; 6 var pc_hand=""; 7 $('#start').on('click',function(){ 8 $('#start').prop('disabled',true); 9 $('#my_hand_id').text(""); 10 my_hand=""; 11 var kakegoe=["じゃん","けん","ぽん"] 12 $('#pc_hand_id').text(""); 13 var timerId=setInterval((function janken(){ 14 if(count==0) pc_hand=["グー","チョキ","パー"][parseInt(Math.random()*3)]; 15 console.log(pc_hand); 16 if($('#instruction').text()=="あい"){ 17 $('#my_hand_id').text(""); 18 $('#pc_hand_id').text(""); 19 } 20 if(kakegoe.length<=count){ 21 clearInterval(timerId); 22 count=0; 23 $('#pc_hand_id').text(pc_hand); 24 $('#instruction').css({opacity:1}); 25 if(my_hand==""){ 26 $('#instruction').text("ださないので負け"); 27 $('#start').prop('disabled',false); 28 }else if(["グー_チョキ","チョキ_パー","パー_グー"].indexOf(my_hand+"_"+pc_hand)>-1){ 29 $('#instruction').text("かち"); 30 $('#start').prop('disabled',false); 31 }else if(["チョキ_グー","パー_チョキ","グー_パー"].indexOf(my_hand+"_"+pc_hand)>-1){ 32 $('#instruction').text("まけ"); 33 $('#start').prop('disabled',false); 34 }else{ 35 my_hand=""; 36 kakegoe=["あい","こで","しょ"]; 37 timerId=setInterval(janken,1000); 38 } 39 }else{ 40 $('#instruction').css({opacity:1}).text(kakegoe[count]).animate({opacity:0}); 41 count++; 42 } 43 return janken; 44 })(),1000); 45 }); 46 $('[data-hand]').on('click',function(){ 47 if(count>0){ 48 my_hand=$(this).data('hand'); 49 $('#my_hand_id').text($(this).data('hand')); 50 } 51 }); 52}); 53</script> 54 55<header> 56<h1>じゃんけんゲーム</h1> 57<button id="start">START</button> 58<br /> 59<br /> 60</header> 61 62<main> 63<div id="instruction"></div> 64<br /> 65<div id="hands"> 66<div>あなた 「<span id="my_hand_id"></span></div> 67<div>コンピュータ 「<span id="pc_hand_id"></span></div> 68</div> 69<br /> 70<div id="judgement"></div> 71</main> 72 73<div id="controller"> 74<ul> 75<li class="my_hand" data-hand="グー">グー</li> 76<li class="my_hand" data-hand="チョキ">チョキ</li> 77<li class="my_hand" data-hand="パー">パー</li> 78</ul> 79</div> 80 81<footer></footer>

投稿2019/10/21 01:42

編集2019/10/21 05:05
yambejp

総合スコア116694

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

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

miyaken912

2019/10/21 03:57

すいませんHTML含め改めて全体像を記載しましたので、こちらで確認頂ければ幸いです。 どうぞ宜しくお願いします。
miyaken912

2019/10/21 08:44

ありがとうございます!記載頂いたコードで期待した通りの動きになりました! 書き方含め参考になりました。 ちなみに、deferredで書く必要はないことは理解したのですが、最初のコードが動かなかった理由は分かりますでしょうか?show_aiko()が何かしら問題があるのだと思うのですが、いくら調べても原因が分からず、もやもやしております・・
yambejp

2019/10/21 08:50 編集

最初に提示いただいたソースは真剣に検証していないのですが、deferredが 複数発生した時に制御するのはかなり難しいのでどこがと言われると 指摘は難しいですね それこそjsのasync/awaitで非同期を同期的な制御に変えれば あいこの処理も可能だと思いますが
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問