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

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

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

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

Q&A

解決済

2回答

1544閲覧

setTimeoutの呼び出し時間が異様に長い

pan2taicho

総合スコア19

JavaScript

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

0グッド

1クリップ

投稿2020/07/30 15:07

編集2020/07/31 00:12

発生している問題

普段は普通に動くが、
たまに、ある箇所のsetTimeoutの呼び出し時間が異様に長くなる。
また、他の処理は普通に動く。

該当のソースコード

Javascript

1count=0; 2function reload(charactor){ 3 console.log("1"); 4 count++; 5 6 //処理省略 7 8 //reloadを呼び出し 9 console.log("2"); 10 myTimer=setTimeout("reload("+charactor+")",40); 11 12 if(count==text[serifukaisu].length){ 13 clearTimeout(myTimer); 14 count=0; 15 serifukaisu++; 16 } 17 console.log("3"); 18}

---追記 余計な情報も多いのですが、コードを丸々コピペしました。

Javascript

1var serifutemp=document.getElementById('pan2serifu').textContent; 2var text=serifutemp.split(","); 3 4function reload(charactor){ 5  console.log("1"); 6 count++; 7 //要素ノードオブジェクト 8 if(charactor===1){ 9 $('#novelsakujo').attr('id',"novel"); 10 var novel=document.getElementById('novel'); 11 $('#novel2').attr('id',"novelsakujo2"); 12 $('#nareta').attr('id',"naretasakujo"); 13 }else if(charactor===2){ 14 $('#novelsakujo2').attr('id',"novel2"); 15 var novel=document.getElementById('novel2'); 16 $('#novel').attr('id',"novelsakujo"); 17 $('#nareta').attr('id',"naretasakujo"); 18 }else if(charactor===3){ 19 $('#naretasakujo').attr('id',"nareta"); 20 var novel=document.getElementById('nareta'); 21 $('#novel').attr('id',"novelsakujo"); 22 $('#novel2').attr('id',"novelsakujo2"); 23 } 24 25 if(skipflag==1){ 26 clearTimeout(myTimer); 27 return 0; 28 } 29 if(text[serifukaisu].substr(count-1,4)=="brbr"){ 30 count=count+4; 31 novel.insertAdjacentHTML('beforeend','<br>'); 32 } 33 if(text[serifukaisu].substr(count-1,2)=="#r"){ 34 count=count+2; 35 var element = document.createElement('span'); 36 element.setAttribute('class', 'red'); 37 element.innerHTML = text[serifukaisu].substr(count-1,1); 38 novel.appendChild(element); 39 }else if(text[serifukaisu].substr(count-1,2)=="&b"){ 40 count=count+2; 41 var element = document.createElement('span'); 42 element.setAttribute('class', 'f34pt'); 43 element.innerHTML = text[serifukaisu].substr(count-1,1); 44 novel.appendChild(element); 45 }else if(charactor===2||charactor===3){ 46 var texttemp=text[serifukaisu].substr(0,text[serifukaisu].length-2); 47 var textNode=document.createTextNode(texttemp.substr(count-1,1)); 48 novel.appendChild(textNode); 49 }else{ 50 var textNode=document.createTextNode(text[serifukaisu].substr(count-1,1)); 51 novel.appendChild(textNode); 52 } 53 console.log("2"); 54 if(hayoflag===0){ 55 myTimer=setTimeout("reload("+charactor+")",40); 56 }else{//メッセージ表示中にエンターを押した場合表示速度を早くする 57 myTimer=setTimeout("reload("+charactor+")",0); 58 } 59 if(count==text[serifukaisu].length){ 60 clearTimeout(myTimer); 61 count=0; 62 serifukaisu++; 63 } 64 console.log("3"); 65}

試したこと

ログの期待値は
123123123...と短時間で続くこと。
しかし、123は一瞬で表示されるが、次の1が表示されるまで、2秒近くかかる。

また、ブラウザをスーパーリロードしても現象は直らないが、
ブラウザを再起動すると直る。
しかし、何日かするとまた同じ現象が発生する。

ちょっとまじでわからないので、可能性だけでも示唆してもらえるとありがたいです。
よろしくお願いします。

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

使用ブラウザ:Google chrome(84.0.4147.105)
OS: windows10

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

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

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

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

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

Yasumichi

2020/07/30 15:27

再帰で書いているのでメモリをどんどん、消費して、ブラウザーの処理が重くなるとかではないですかね?メモリ監視をしてみると良いかもしれません。 はずしてたらごめんなさい。
pan2taicho

2020/07/30 16:30

すみません、再起は数回で抜ける処理になってます メモリも問題なし、またChromeのperformanceで見たときに、jsは問題なしでidleの時間だけが長いという状況です
miyabi_takatsuk

2020/07/30 17:01

再帰をやめて、setIntervalを使うべきだと思います。 一定時間で繰り返しは、setTimeoutでやるべきではありません。 (制御できないタイマーが増え続ける可能性がある)
m.ts10806

2020/07/30 20:41 編集

「charactor」には何を与えているのでしょう。文字列だと動かないですよね。
m.ts10806

2020/07/30 20:42

textという変数もそうですね。せめてコピペで動作確認できる情報をください
pan2taicho

2020/07/31 00:15

ソースコードをコピペしてきました。charactorには1か2か3が入ってます。 setIntervalに修正して試してみます。 ありがとうございますm(_ _)m
guest

回答2

0

ベストアンサー

なぜ重くなっているか、
無限ループが発生しているからです。

下記構文を実行してみてください。

javascript

1count=0; 2serifukaisu=0; 3function reload(charactor){ 4 // console.log("1"); 5 count++; 6 7 //処理省略 8 9 //reloadを呼び出し 10 // console.log("2"); 11 myTimer=setTimeout("reload("+charactor+")",40); 12 13 console.log("set:", myTimer); 14 15 if(count==100){ 16 console.log("clear:", myTimer); 17 clearTimeout(myTimer); 18 count=0; 19 serifukaisu++; 20 } 21 // console.log("3"); 22} 23 24reload(count);

セットが大量に発生しており、
クリアは、その場でのタイマーにしかクリアを適用できていなく、
使徒不明のタイマーIDが大量発生しているのがわかるかと思います。
(不明変数は固定値に置き換えてます)

設計から見直すべきで、
タイマーは外側スコープに一個、(つまり、letで定義し、スコープを明確にする)、
setIntervalを使うべきです。

投稿2020/07/31 03:35

miyabi_takatsuk

総合スコア9555

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

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

m.ts10806

2020/07/31 05:59

40ミリ秒 なんて一瞬レベルしか待たせないなら普通に自身呼び出してreturnさせたほうがいいのではと思ってみたり。
miyabi_takatsuk

2020/07/31 06:20

ですね。 して、再帰の基本はそれですよね。 setTimeoutを使った意図があるかもですが、これ以上は聞いてみないと答えようがないですね 汗
pan2taicho

2020/07/31 06:57

おかげさまで解決しました、ありがとうございましたm(_ _)m ノベルゲーム風に文字を一文字一文字表示させるというコードなので、40という短い時間に設定していました。
guest

0

皆さま、ご回答ありがとうございましたm(_ _)m
setIntervalで解決しました。

投稿2020/07/31 06:52

pan2taicho

総合スコア19

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問