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

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

ただいまの
回答率

90.50%

  • JavaScript

    16461questions

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

  • 関数

    220questions

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

0.0166秒後と1秒後の関係性

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 317

aaaaaaaa

score 469

関数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();
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    退会済みユーザー

    2017/10/30 19:49

    コードがないと理解しづらいです

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2017/10/30 19:49

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

    キャンセル

回答 2

+2

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

'use strict';
function A (delay, callbackfn) {
  setTimeout(callbackfn, delay);
  B(1000, function () { console.log('B'); });
}

function B (delay, callbackfn) {
  setTimeout(callbackfn, delay);
}

A(16.6, function () {
  console.log('A');
});
  • A()B() 共に即時実行されています
  • 16.6ミリ秒後に A() が実行されているわけではありません (Aの実行は既に終わっています)
  • 1000ミリ秒後に B() が実行されているわけではありません (Bの実行は既に終わっています)

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

Re: aaaaaaaa さん

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/31 17:41

    ご回答ありがとうございます。
    質問文に間違いがござました。

    本来このように書くべきでした。
    "関数内関数Bを実行した時点でsettimeout(B,1000)も実行されています。
    関数内関数Bを実行した後、関数Aにも設定したsettimeout(A,1000/60)を実行します。"

    せっかくご回答してくださったのに誠に申し訳ございません。

    キャンセル

  • 2017/10/31 18:43

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

    キャンセル

  • 2017/10/31 19:42

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

    キャンセル

checkベストアンサー

+1

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

var interval = Math.floor(1000/60); 
function draw() {
  function siraberu() {
    setTimeout(siraberu, 1000);
  }
  siraberu();
  setTimeout(draw,interval);
}
function siraberu2() {
  setTimeout(siraberu2, 1000);
}
draw();
siraberu2();


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

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

秒数 起こること
0.000 drawが呼ばれる
0.000 siraberuが呼ばれる
0.000 1.000にsiraberuを予約
0.000 0.016にdrawを予約
0.000 siraberu2が呼ばれる
0.000 1.000にsiraberu2を予約
0.016 drawが呼ばれる
0.016 siraberuが呼ばれる
0.016 1.016にsiraberuを予約
0.016 0.032にdrawを予約
0.032 drawが呼ばれる
0.032 siraberuが呼ばれる
0.032 1.032にsiraberuを予約
0.032 0.048にdrawを予約
以下略

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.50%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    16461questions

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

  • 関数

    220questions

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