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

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

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

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

解決済

2回答

290閲覧

0.0166秒後と1秒後の関係性

aaaaaaaa

総合スコア501

JavaScript

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

0クリップ

投稿2017/10/30 10:47

編集2017/10/31 10:41

関数Aとその関数内に存在する関数Bの両方に、第一引数で指定した関数を第二引数秒後に実行し続けるsettimeout()を指定したとします。
設定秒数は、関数Aのほうが0.0166秒、関数ない関数Bの設定秒数が1秒とし、関数内関数Bは、関数A内で実行します。関数内関数Bを実行した時点でsettimeout(B,1000)も実行されています。
関数内関数Bを実行した後、関数Aにも設定したsettimeout(A,1000/60)を実行します。

ここで一つ疑問が生まれました。
関数Aが実行されて、その関数A内にある関数Bも実行されます。このあとsettimeoutで関数Aが0.01666...秒後、関数内関数Bが1秒後に実行されていきます。
秒数だけ見ると関数Aのほうが早く実行されるのは分かりますが、一秒後に実行される関数Bとの関係性が分かりません。最初に関数A、Bが実行されると、次の動作は、Aが0.0166秒後にAの処理を実行し、
Bも1秒後にBを実行しますが、その間Aが0.0166秒後に実行されるのですから、0.01666秒後に再度AとBが実行されます。ちょっと頭が混乱しますがBがだぶっているようにみえます。
試しに上記のような処理を作ってみると、明らかにAの設定秒数である0.01666秒で関数Bが動いているようにみえました。
恐らくですが、関数Bのsettimeoutで1秒後に関数Bが実行される前にAが何かしらの影響を与えているのでは、と思っています。
しかしこれといった答えを出せているわけではないですし、推測の域を出ないですし、頭がこんがらがってくるのでこれは、もう質問サイトに投稿するしかないだろう、ということで投稿しました。
いったいこのへんは、どうなっているのでしょうか。

//①canvas要素の取得 var canvas = document.getElementById("canvas"); //②canvas要素から描画コンテキストの取得 var ctx = canvas.getContext("2d"); //1秒間に60回分(つまり1回につき0.01666秒、描画している)、長方形を描画している //16.6ミリ秒(0.01666...秒) var interval = Math.floor(1000/60); var x=5; var y=5; //測量 var count = 0; //console.time("time"); function draw() { ctx.clearRect(0,0,500,500); x+=5; y+=5; //単純に数字を既定の数まで加算しているだけなので厳密に時間を計っているわけではないから、これであっているのだろうか。 //1000ミリ秒後に再度、siraberuを実行するので1、2、3、4…と秒数が表示されるのかと思いきや、図形が描画される速さと同じ速さで秒数を測定してしまう //drewと何か影響があるのか・・・ function siraberu(){ if(count<=20) { document.getElementById("count").textContent= count+"秒経った"; setTimeout(siraberu,1000); count += 1; } } //パスを初期化。ここでいうパスとは、領域の境界線のようなものだという。 ctx.beginPath(); //塗りつぶす色を指定。 ctx.fillstyle = "#99ff66";//緑色 //長方形のパスを作成。第一引数がx座標(横)、第二引数がy座標(縦)、第三引数が横幅、第四引数が高さだ。座標というのは、ブラウザの表示領域のX軸とY軸のことだ。0,0にすれば、ブラウザの左上に表示される。 ctx.rect(x,y,100,200);//rectは、rectangel(長方形、矩形)の略である。 //fillで長方形を塗りつぶす。何も指定しないと黒色となる。 ctx.fill();//fillは、容器や場所などをいっぱいにする、満たすという意味だ。 //最後にbeginPathで開始したパスを閉じる。 ctx.closePath(); siraberu(); //console.time("time2"); setTimeout(draw,interval); //console.timeEnd("time2"); } //描画し終えてから秒数を測定してしまう var count2 =0; function siraberu2(){ if(count2<=20) { document.getElementById("count2").textContent= count2+"秒立った"; setTimeout(siraberu2,1000); count2 += 1; } } draw(); //console.timeEnd("time"); siraberu2();

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2017/10/30 10:49

コードがないと理解しづらいです
退会済みユーザー

退会済みユーザー

2017/10/30 10:49

コードがないと何言ってるか分かりづらいです。
guest

回答2

0

コードは下記で合っていますか。

JavaScript

1'use strict'; 2function A (delay, callbackfn) { 3 setTimeout(callbackfn, delay); 4 B(1000, function () { console.log('B'); }); 5} 6 7function B (delay, callbackfn) { 8 setTimeout(callbackfn, delay); 9} 10 11A(16.6, function () { 12 console.log('A'); 13});
  • A(), B() 共に即時実行されています
  • 16.6ミリ秒後に A() が実行されているわけではありません (Aの実行は既に終わっています)
  • 1000ミリ秒後に B() が実行されているわけではありません (Bの実行は既に終わっています)

setTimeout() はタイマー処理を登録する関数です。
指定した遅延時間経過後にタイマーイベントが発火するようなものだと思ってください。

Re: aaaaaaaa さん

投稿2017/10/30 11:23

think49

総合スコア18156

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

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

aaaaaaaa

2017/10/31 08:41

ご回答ありがとうございます。 質問文に間違いがござました。 本来このように書くべきでした。 "関数内関数Bを実行した時点でsettimeout(B,1000)も実行されています。 関数内関数Bを実行した後、関数Aにも設定したsettimeout(A,1000/60)を実行します。" せっかくご回答してくださったのに誠に申し訳ございません。
think49

2017/10/31 09:43

文章による説明はすれ違いの元なので、現在のコードを質問文に追記して下さい。
aaaaaaaa

2017/10/31 10:42

ご返答ありがとうございます。ソースを追加しました。
guest

0

ベストアンサー

まずあなたのコードを最低限に減らして見てみます。

JavaScript

1var interval = Math.floor(1000/60); 2function draw() { 3 function siraberu() { 4 setTimeout(siraberu, 1000); 5 } 6 siraberu(); 7 setTimeout(draw,interval); 8} 9function siraberu2() { 10 setTimeout(siraberu2, 1000); 11} 12draw(); 13siraberu2();

まずsiraberuのsetTimoutを削除しても「drawと同時にsiraberuが実行されている」という現象は変わりません。なぜならdrawの中に普通にsiraberu()と書いているんですから、drawと同時にsiraberuが実行されることはなんら不思議ではありません。

さらにここにsetTimeoutがからまることでよりわけのわからないことになっています。
各setTimeoutによる周回のことをdrawループ、siraberuループ、siraberu2ループと名付けることにします。ここでどのようなことが起こるかを順に見てみます。秒数は処理自体に一切時間がかからないものとした秒数です。

秒数起こること
0.000drawが呼ばれる
0.000siraberuが呼ばれる
0.0001.000にsiraberuを予約
0.0000.016にdrawを予約
0.000siraberu2が呼ばれる
0.0001.000にsiraberu2を予約
0.016drawが呼ばれる
0.016siraberuが呼ばれる
0.0161.016にsiraberuを予約
0.0160.032にdrawを予約
0.032drawが呼ばれる
0.032siraberuが呼ばれる
0.0321.032にsiraberuを予約
0.0320.048にdrawを予約
以下略

ループの中でさらにsetTimeoutを呼ぶ、ということはループするたびにループが生まれるという恐ろしいことになります。そもそも0.016のdrawループと1秒のsiraberuループは「並列」に「1回ずつ」始めればよいのであって、siraberu2だけあれば事足りているかと思います。

投稿2017/11/08 02:20

masaya_ohashi

総合スコア9206

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問