[45] [DFN[[CODE(DOMm)@en[[[setTimeout()]]]]]] と [DFN[[CODE(DOMm)@en[[[setInterval()]]]]]] は、一定時間後、あるいは一定時間ごとに指定した処理を実行するものです。 * 仕様書 [REFS[ - [33] '''[CITE@en-US-x-hixie[HTML Standard]] ([TIME[2013-07-27 01:56:00 +09:00]] 版) ''' - [47] [CITE@en-US-x-hixie[HTML Standard]] ([TIME[2014-04-03 03:44:44 +09:00]] 版) ]REFS] * 定義 [46] [DFN[[CODE(DOMi)@en[[[WindowTimer]]]]]] [[インターフェイス]]は、[[メソッド]] [DFN[[CODE(DOMm)@en[[[setTimeout]]]]]], [DFN[[CODE(DOMm)@en[[[setInterval]]]]]], [DFN[[CODE(DOMm)@en[[[clearTimeout]]]]]], [DFN[[CODE(DOMm)@en[[[clearInterval]]]]]] を持ちます [SRC[>>33]]。 [CODE(DOMi)@en[[[WindowTimer]]]] は [CODE(IDL)@en[[[NoInterfaceObject]]]] であり、 [CODE(DOMi)@en[[[Window]]]] [SRC[>>33]] と [CODE(DOMi)@en[[[WorkerGlobalScope]]]] [SRC[>>47]] が[[実装]]しています。 * タイマー設定メソッド [48] [CODE(DOMm)@en[[[setTimeout]]]] と [CODE(DOMm)@en[[[setInterval]]]] は、 1つ以上の[[引数]]が必要です [SRC[>>33]]。いずれも[[タイマー初期化手順]]を実行するものです [SRC[>>33]]。 [49] 第1引数は、一定時間後に実行されるべきコードを指定します。[[データ型]]は [CODE(DOMi)@en[[[Function]]]] または [CODE(DOMi)@en[[[DOMString]]]] です [SRC[>>33]]。 [50] 第2引数は、コードが実行されるまでの時間です。[[データ型]]は [CODE(IDL)@en[[[long]]]] で、省略した場合の[[既定値]]は [CODE[[[0]]]] です [SRC[>>33]]。 [51] 第3引数以降は、任意の値を指定でき [SRC[>>33]]、コードへの[[引数]]として使われます。 [52] [[メソッド]]の返り値は、 [CODE(IDL)@en[[[long]]]] です [SRC[>>33]]。 * タイマー消去メソッド [53] [CODE(DOMm)@en[[[clearTimeout]]]] と [CODE(DOMm)@en[[[clearInterval]]]] には [[long]] の[[引数]]を1つ指定できます [SRC[>>33]]。省略した場合の[[既定値]]は [CODE[[[0]]]] です [SRC[>>33]]。 [54] [[メソッド]]の返り値はありません [SRC[>>33]]。 [57] いずれも、[[活性タイマーのリスト]]から[[引数]]で指定された[[数]]により識別される項目があれば、 これを消去します。該当するものがなければ、何もしません。 [SRC[>>33]] ;; [58] どちらのメソッドも、同じように動作します。 [VAR@en[repeat]] フラグは無視されます。 * 活性タイマーのリスト [55] [CODE(DOMi)@en[[[WindowTimer]]]] [[オブジェクト]] ([CODE(DOMi)@en[[[Window]]]] や [CODE(DOMi)@en[[[WorkerGlobalScope]]]]) は[DFN[[RUBYB[[[活性タイマーのリスト]]]@en[list of active timers]]]]を持ちます [SRC[>>33]]。[[活性タイマーのリスト]]には、 [CODE(DOMm)@en[[[setTimeout]]]] や [CODE(DOMm)@en[[[setInterval]]]] で指定された[[タイマー]]が含まれます。 [[活性タイマーのリスト]]内の各項目は、[[非負整数]]により識別されます [SRC[>>33]]。 この[[数]]は、 [CODE(DOMi)@en[[[WindowTimer]]]] [[オブジェクト]]の生存期間内において固有でなければ[['''なりません''']] [SRC[>>33]]。 ;; [56] ということは [CODE(IDL)@en[[[long]]]] で表せる[[数]]の回数以上はタイマーを使えないことになります。 * タイマー初期化手順 [59] [DFN[[RUBYB[タイマー初期化手順]@en[timer initialization steps]]]]には、次のような内容が含まれています [SRC[>>33]]。 [FIG[ = [60] [VAR@en[handle]] は、 >>65 からの呼び出しならもとの [VAR@en[handle]]、 そうでなければ[[利用者エージェント]]定義の[[非負整数]]とします。 後者の場合は、 [VAR@en[handle]] を識別子とする項目を[[活性タイマーのリスト]]に追加します。 = [61] 次のような[[タスク]]を用意します。 -= [63] 本項目が[[活性タイマーのリスト]]から既に消去されていれば、何もしません。 -= [64] 指定されたコードを実行します (>>77)。 -= [65] [CODE(DOMm)@en[[[setInterval]]]] だった場合は、[[タイマー初期化手順]]を呼び出します。 = [66] [VAR@en[timeout]] を第2引数の値とします。 = [67] 現在実行中の[[タスク]]の[[タイマー入れ子水準]] (なければ 0) が5より大きく、 [VAR@en[timeout]] が4より小さいなら、 [VAR@en[timeout]] を4にします。 = [62] >>61 の[[タスク]]の[[タイマー入れ子水準]]を現在実行中の[[タスク]]の[[タイマー入れ子水準]] (なければ 0) + 1 とします。 = [68] [VAR@en[handle]] を返します。この続きは[[非同期的]]に継続します。 = [69] 待ちます。 == [70] [[文脈オブジェクト]]が [CODE(DOMi)@en[[[Window]]]] なら、関連付けられている[[文書]]が[[完全に活性]]な状態を [VAR@en[timeout]] [[ミリ秒]] (連続的でなくても構いません)。 == [71] [[文脈オブジェクト]]が [CODE(DOMi)@en[[[WorkerGlobalScope]]]] なら、[[ワーカー]]が [[suspend]] されていない状態を [VAR@en[timeout]] [[ミリ秒]] (連続的でなくても構いません)。 == [72] 同じ[[文脈オブジェクト]]で実行された[[タイマー初期化手順]]で、本呼び出しより前に呼び出されたもので、 [VAR@en[timeout]] が本呼び出し[[以下]]のものが完了するまで。 == [73] [[利用者エージェント]]定義の時間。 = [74] >>61 の[[タスク]]を[[キュー]]に追加します。[[タスク源]]は[[タイマータスク源]]とします。 ]FIG] [76] [DFN[[RUBYB[[[タイマータスク源]]]@en[timer task source]]]] [SRC[>>33]] は、 [CODE(DOMm)@en[[[setTimeout]]]] と [CODE(DOMm)@en[[[setInterval]]]] により追加される[[タスク]]で使われる[[タスク源]]です。 [77] 指定されたコードは次のように実行されます [SRC[>>33]]。 [FIG[ - [78] [CODE(JS)@en[[[Function]]]] の場合、これを呼び出します。 -- [79] [CODE(JS)@en[[[thisArg]]]] は[[文脈オブジェクト]]を使います。ただし [CODE(DOMi)@en[[[Window]]]] であれば、対応する [CODE(DOMi)@en[[[WindowProxy]]]] を使います。 - [80] [CODE(DOMi)@en[[[DOMString]]]] の場合、[[スクリプトを作成]]します。 -- [81] スクリプト源は指定された [CODE(DOMi)@en[[[DOMString]]]] とします。 -- [82] [[スクリプト言語]]は [[JavaScript]] とします。 -- [83] [[設定オブジェクト]]は[[文脈オブジェクト]]の[[スクリプト設定群オブジェクト]]とします。 ]FIG] ;; [84] [[スクリプトの作成]]の手順は、[[スクリプト]]を作って実行します。 ;; [85] [CODE(DOMm)@en[[[setInterval]]]] の場合、毎回[[スクリプト]]のコンパイルから行われることになります。 * タイマーの精度 [31] 元々は最小でも 10ms とされていましたが、後に実装によっては最小 4ms となり、 >>27 で仕様もそれに揃いました。更に入れ子回数 (タイマーによる処理によって更にタイマー処理を予定した回数) が4回までは 4ms の制限すらも撤廃されるようになり、仕様も >>24 で追随しています。 [32] なお、いずれにせよ、[[利用者エージェント]]は指定された時間に厳密に従う必要はなく、 利用できる資源の制約や性能上の限界その他の要因により前後する可能性があります。 [75] [DFN[[RUBYB[[[タイマー入れ子水準]]]@en[timer nesting level]]]] [SRC[>>33]] は、 この入れ子回数の管理のための値です。[[タイマー初期化手順]]により追加された[[タスク]]に存在します。 * 歴史 [2] [CITE[IRC logs: freenode / #whatwg / 20070409]] ([CODE[2007-04-12 00:04:42 +09:00]] 版) ([[名無しさん]] [WEAK[2007-04-11 15:37:28 +00:00]]) [6] [CITE@en[Re: Proposal: High resolution (and otherwise improved) timer API]] ([[Maciej Stachowiak]] 著, [CODE[2008-10-04 06:21:35 +09:00]] 版) >I cannot state with certainty that nothing lower than 10ms is safe. Chrome shipped with a 1ms delay and that was found to create problems on a number of sites, including nytimes. They are planning to try 4ms next. We would consider using a lower limit in the official webkit.org version of WebKit, not not as low as 1ms. [9] [CITE[IRC logs: freenode / #whatwg / 20090504]] ([TIME[2009-08-05 07:43:45 +09:00]] 版) [10] [CITE['''['''webkit-dev''']''' setTimeout as browser speed throttle]] ([TIME[2008-10-01 15:56:01 +09:00]] 版) [12] [CITE@en[Web Applications 1.0 r5535 Allow timers to be delayed when power usage is an issue.Fixing http://www.w3.org/Bugs/Public/show_bug.cgi?id=10633]] ( ([TIME[2010-09-29 07:08:00 +09:00]] 版)) [13] [CITE[Bug 10633 – Minimums for timer granularity should be left to the user agent - different form factors have different power requirements]] ( ([TIME[2010-09-29 07:19:30 +09:00]] 版)) [14] [CITE[''''''[''''''whatwg'''''']'''''' Timeouts and monotonic vs clock time]] ( ([TIME[2011-01-09 13:44:38 +09:00]] 版)) [15] [CITE['''['''whatwg''']''' setTimeout clamps]] ([TIME[2011-01-16 12:00:52 +09:00]] 版) [16] [CITE@en[Web Applications 1.0 r5879 Define 'this' for setTimeout functions]] ( ([TIME[2011-02-12 08:50:00 +09:00]] 版)) [17] [CITE@en[Web Applications 1.0 r6492 Explain ordering of setTimeout() calls better]] ( ([TIME[2011-08-18 06:36:00 +09:00]] 版)) [18] [CITE@en[Web Applications 1.0 r6899 Make setTimeout() not be well-ordered across multiple browsing contexts, so as to allow user agents to e.g. throttle setTimeout()s in background tabs.]] ( ([TIME[2012-01-18 07:13:00 +09:00]] 版)) [19] [CITE@en[Web Applications 1.0 r6949 Turns out clearTimeout() and clearInterval() are synonyms! Who knew? Oh what a tangled Web we weave.Fixing https://www.w3.org/Bugs/Public/show_bug.cgi?id=14907]] ( ([TIME[2012-02-01 05:20:00 +09:00]] 版)) [20] [CITE[IRC logs: freenode / #whatwg / 20120626]] ( ([TIME[2012-07-12 23:44:39 +09:00]] 版)) [21] [CITE@en-US[Window Object 1.0]] ( ([TIME[2006-04-08 02:19:28 +09:00]] 版)) [22] [CITE@en[Bug 15007 – Add an API to queue a task]] ( ([TIME[2013-02-09 22:45:48 +09:00]] 版)) [23] [CITE@en[Web Applications 1.0 r7737 Try to more closely match reality.]] ( ([TIME[2013-03-07 08:03:00 +09:00]] 版)) [24] [CITE@en[Web Applications 1.0 r8095 Refactor the timer code to match current practice in WebKit, Gecko, and Blink (the ones whose source I could examine)]] ( ([TIME[2013-07-27 08:27:00 +09:00]] 版)) [25] [CITE[Bug 376643 – setInterval fires repeatedly with incorrectly small delays if machine is suspend/resumed, hibernate/resumed or process is SIGSTOP/SIGCONT]] ([CODE[2007-06-23 10:13:26 +09:00]] 版) [26] [CITE[HTML5 IRC logs: freenode / #whatwg / 20070622]] ([TIME[2007-06-23 10:17:05 +09:00]] 版) ([[名無しさん]] [WEAK[2007-06-23 01:21:49 +00:00]]) [27] [CITE@en[Web Applications 1.0 r6362 Make setInterval() clamp at 4ms as well.]] ( ([TIME[2011-08-04 08:54:00 +09:00]] 版)) [34] [CITE@en[Efficient Script Yielding]] ([TIME[2013-07-23 11:06:32 +09:00]] 版) * メモ [1] [CITE[Scope of setTimeout Method]] [7] [CITE[for 文を setTimeout に変換する - IT戦記]] ([TIME[2009-02-02 01:57:56 +09:00]] 版) [8] [CITE[JSDeferred を高速化する (試し中) - 冬通りに消え行く制服ガールは、夢物語にリアルを求めない。 - subtech]] ([TIME[2009-03-31 08:34:10 +09:00]] 版) [28] [CITE[zarame.com/zide/ 日記(2005-11-24)]] ([[名無しさん]] [WEAK[2005-12-07 11:45:55 +00:00]]) [29] [CITE[ぷろじぇくと、みすじら。]] ([[名無しさん]] [WEAK[2005-12-07 11:46:42 +00:00]]) [30] [CITE[zarame.com/zide/ 日記(2005-11-28)]] ([[名無しさん]] [WEAK[2005-12-07 11:46:56 +00:00]]) [35] [CITE[setIntervalとsetTimeoutを調べた結果余分なことになった - 三等兵]] ( ([TIME[2013-07-24 01:30:24 +09:00]] 版)) [36] [CITE@en-US[window.setTimeout - Web API reference | MDN]] ( ([TIME[2013-07-10 02:55:41 +09:00]] 版)) [37] [CITE[Issue 792 - chromium - TRACKING: Chrome does not implement the Webkit 10ms setTimeout clamp. - An open-source project to help move the web forward. - Google Project Hosting]] ( ([TIME[2013-07-27 05:59:41 +09:00]] 版)) [38] [CITE@en-US[David Baron's weblog: setTimeout with a shorter delay]] ( ([TIME[2013-07-27 05:59:54 +09:00]] 版)) [39] [CITE@en[123273 – setTimeout(something, 0) causes 100% CPU constant]] ( ([TIME[2013-07-27 06:07:25 +09:00]] 版)) [40] [CITE@en[686201 – implementation: setImmediate API]] ( ([TIME[2013-07-27 06:16:49 +09:00]] 版)) [41] [CITE@en[839816 – Make next-tick mechanisms like postMessage faster]] ( ([TIME[2013-07-27 06:36:50 +09:00]] 版)) [42] [CITE[''''''[''''''whatwg'''''']'''''' Proposal: requestBackgroundProcessing()]] ( ([TIME[2014-02-20 21:38:44 +09:00]] 版)) [43] [CITE@en[Web Applications 1.0 r8535 Move a setTimeout() requirement from prose to IDL.]] ( ([TIME[2014-03-08 07:55:00 +09:00]] 版)) [44] [CITE@en[Web Applications 1.0 r8508 Make clearTimeout()/clearInterval() (with no arguments) into no-ops; change the role mapping so that tables aren't interactive.]] ( ([TIME[2014-02-25 03:44:00 +09:00]] 版))