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

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

ただいまの
回答率

90.47%

  • JavaScript

    17034questions

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

  • HTML

    9294questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • jQuery

    6934questions

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

setTimeoutの処理の動きを理解したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,640

k499778

score 502

前回の投稿の続きです。
Ajaxを使うとsetTimeout処理がうまくいかない

現在HTML,Javascript(jQuery)を使ってアプリを作っています。

前回の投稿に画面デザインとコードがあるのですが、

setTimeout内で書いたAjaxコードは,clearTimeoutをしても
リクエストが飛ぶ、もしくは、飛ぶことがある。
ということがわかりました。

そこで

setTimeoutの処理の動きを理解したい

と思い、質問しました。

単刀直入に考えをぶつけると、
setTimeout内の処理は、n秒後に処理が流れて実行されるわけでなく、
n秒経つ前にすでに処理は流れていて、それがn秒後に実行されるのでしょうか?

前回コードの動きのイメージは以下でした。

1.文字入力後、setTimeoutで0.5秒後に実行される処理を予約する
2.ボタン押下し、clearTimeoutで予約していた処理をキャンセルする
3.そのためsetTimeout内に書かれているAjaxの処理は走らない

ただ今回の動きを見て、またアドバイスから、動きのイメージはこうでしょうか?

1.文字入力後、setTimeoutで0.5秒後に実行される処理を予約する。すでに処理は流れているが、実行されない。
2.ボタン押下し、clearTimeoutで予約していた処理をキャンセルする
3.リクエストを投げていたAjaxの処理が実行されることがある

やはり知りたいのは
setTimeout内の処理は、n秒後に処理が流れて実行されるわけでなく、
n秒経つ前にすでに処理は流れていて、それがn秒後に実行されるのでしょうか?

ということになると思います。

例えば前回コードのAjax処理の上に
console.log('テスト');
があった場合、この処理も
setTimeoutのn秒後に実行される前に流れているのでしょうか?
それともAjaxに限ったことなのでしょうか?

長くなってしまいましたが、setTimeoutとAjaxの動きについてわかる方がいらっしゃいましたら、お答えいただけると有難いです。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+2

Ajaxの場合、「結果が帰ってきてから行われる処理」は、ちょうどsetTimeout()の例のように、別個に実行されます。ということで、時間が経つギリギリぐらいにボタンを押した場合、

  1. Ajaxのリクエストが送信されて、「リクエストを受け取った場合の処理」が設定される
  2. clearTimeout()で、「リクエストを送る処理」が削除される
  3. リクエストが帰ってくると、2で削除されたのとは全く別個に、「リクエストを受け取った場合の処理」が動く

という流れになっています。「setTimeout()してもその場で実行される」なんてことはありません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/04/23 13:48 編集

    回答ありがとうございます。
    大方悩みが解消されました。

    完全に理解するためにもう少し踏み込んでお聞きしたいのですが、

    setTimeout内の処理は時間が経つ前に流れることはない。が,
    setTimeout内のAjax処理は流れている(=リクエストを投げている)。
    それはAjaxが別個(=非同期?別スレッド?)で実行されるから。

    という認識で合っていますか?

    また、別個で実行されるのに、
    clearTimeout()で、「リクエストを送る処理」が削除される
    のも腑に落ちません。

    もしお答えいただけたら教えていただきたいです。

    キャンセル

  • 2016/04/23 14:17

    clearTimeoutをしたときAjaxのリクエストが飛んだり飛ばなかったりしていたのは、
    次のような認識で合っているでしょうか?

    1. Ajax処理は別個で実行されるため、setTimeout内でも実行される。
    2. そのAjaxのリクエストを投げる処理が,clearTimeoutの前に実行された場合は、レスポンスを返してしまう。
    3. そのAjaxのリクエストを投げる処理よりも前に,clearTimeoutが実行された場合は、リクエスを投げる処理が削除されるためレスポンスを返さない。

    文字入力してからすぐAjax処理が実行されるわけでない?実行されるまでに少しのタイムラグが生じる?のでその間にclearTimeoutされるかされないかでAjaxが実行されるかされないかが変わる。

    このような感じで合ってますしょうか?

    Ajaxは別個に実行されるとはいえ、setTimeoutで設定されている秒数、0.5秒後に実行されるのでしょうか?

    多くの質問を投げてしまい申し訳ないですが、お答えいただければと思います。

    キャンセル

  • 2016/04/23 18:52

    横から失礼します。k499778 さんは、イベントドリブンというメカニズムをきちんと勉強されるとよいと思います。
    ・「ユーザがある DOM 要素をクリックした」「指定された時間が経過した」「非同期で送ったリクエストに対するレスポンスが返ってきた」など、すべて「イベント」です。
    ・あるイベントが発生したときに実行すべき処理を「イベントハンドラ」と言います。イベントにイベントハンドラが登録されていると、そのイベントが発生したときにそのイベントハンドラが実行されます。
    ・一度登録したイベントハンドラを削除することができます。

    「$().on(イベント名, イベントハンドラ)」「setTimeout(イベントハンドラ, タイムアウトイベントが発生する時間)」「$.ajax()」など、いずれもイベントハンドラの登録です。「$().off()」はイベントハンドラの削除、「crearTimeout()」はイベントハンドラを削除しますし、タイムアウトイベント自体が発生しなくなります。

    ということを踏まえますと、
    1. 文字入力イベントのハンドラの中で setTimeout でタイマーを設定する(タイムアウトイベントを発生させるタイマーの設定&タイムアウトイベントハンドラを登録する)
    2. 0.5 秒経ち、タイムアウトイベントが発生し、ハンドラが起動する。このタイムアウトイベントハンドラの中で ajax のレスポンス受信イベントのハンドラをセットして ajax リクエストを投げる
    3. ボタン押下イベントハンドラの中でタイマーを削除する(もしかしたらすでにないかも)。
    4. ajax レスポンスが戻ってきてレスポンス受信イベントが発生する。登録されているレスポンス受信イベントハンドラが実行される。

    という動きです。縦でも横でもいいですから時間軸を設定して、どのタイミングでどういうイベントのハンドラが登録されているか、どういうタイミングがだとイベントハンドラの登録削除が行われるか、どこでイベントが発生しイベントハンドラが実行されるか、を図に描いてみることをおすすめします。

    キャンセル

  • 2016/04/24 00:56 編集

    unauさん回答ありがとうございます。
    大変勉強になりました。
    時間軸を自分でも書いてみました。またイベントドリブンも勉強してみます。

    それを踏まえた上で質問させてください。

    今回の事象は0.5秒後のことではないでしょうか?
    0.5秒以内のことだと勝手に思っており、AjaxのclearTimeoutが効かない。と勝手に思っていましたが、そうではなく、
    今回ボタン押下時も赤色になるパターンは

    1. 0.5秒経ち、setTimeoutが実行され、Ajaxがリクエストを投げる
    2. ボタン押下の青色に変える処理が実行される
    3. Ajaxのレスポンスをが返ってきて赤に変える処理が実行される
      →ボタン押下したにも関わらず、赤になる時がある

    ということではないでしょうか?

    0.5秒以内のときはclearTimeoutにより、Ajax処理を含めたsetTimeoutイベント削除するため、Ajax処理は実行されていない。


    この認識なのではないかと考えています。

    もしお答えいただければよろしくお願いします。

    キャンセル

  • 2016/04/24 07:27

    起こっている事象は複雑に見えますが、ひとつひとつの「イベント発生」「イベントハンドラ登録」「タイマーイベントの登録」「タイマーイベントの削除」「イベントハンドラの実行」それぞれは単純です。タイマーを併用すると ajax 自体の動きが変わる、とかはありません。タイマーはタイマー、ajax は ajax、それぞれお互いに関係なく動きます。

    おっしゃるように、0.5秒以内のときは ajax リクエストは飛ばない、すなわち、ボタン押下でも赤になるのは 0.5秒すぎて ajax リクエストが飛んだ場合、と推測されます。ajax はネットワーク越しにリクエストを投げるわけですから、当然、いくばくかの時間がかかります。

    失礼ながら、一連の質問を背景していますと、ちょっと前のめりになりすぎている感じがしますので、もう一度、過去の質問につけられた回答やコメントを熟読し、しっかり理解されるとよいと思います。イベントドリブンなシステムをきちんと理解できていれば、さほど難しいことをアドバイスされているのではないというのがわかるかと思います。

    キャンセル

  • 2016/04/24 10:20 編集

    返答ありがとうございます。
    アドバイスのおかげで
    今回のボタン押下したのに、赤になってしまうケースに関しては理解できてきたように思います。

    ・今回のケースは0.5秒以上経って、普通にsetTimeout処理が実行されたケース。
    ・そしてAjaxのリクエストを投げて、レスポンスが返ってくるまでの間に、ボタン押下の処理が実行されたケース
    ・Ajaxのリクエストとレスポンスの間には、ネットワーク越しの処理なので多少の時間がかかるため、その間にボタン押下処理が実行されてしまうことがある


    setTimeout処理が実行されていないにもかかわらず、Ajax処理が別個に実行されるような解釈をしてしまい、clearTimeoutしてもAjaxだけは実行されているのかなと思ってしまって、すごくややこしくなっていました。

    ただsetTimeoutが実行された後ということなら、すんなり自分の中に落としこむ事ができそうです。

    それもunauさんを始め、多くの方のアドバイスがあったからです。

    仰るとおり、まだまだ未熟な部分は多分にございますので、
    イベントドリブンの勉強をし、日々精進していきます。
    長々と付き合ってくださりありがとうございました。

    キャンセル

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

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

関連した質問

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

  • JavaScript

    17034questions

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

  • HTML

    9294questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • jQuery

    6934questions

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