[html5] r8095 - [giow] (3) Refactor the timer code to match current practice in WebKit, Gecko, a [...]
whatwg at whatwg.org
whatwg at whatwg.org
Fri Jul 26 16:27:46 PDT 2013
Author: ianh
Date: 2013-07-26 16:27:44 -0700 (Fri, 26 Jul 2013)
New Revision: 8095
Modified:
complete.html
index
source
Log:
[giow] (3) Refactor the timer code to match current practice in WebKit, Gecko, and Blink (the ones whose source I could examine)
Fixing https://www.w3.org/Bugs/Public/show_bug.cgi?id=22631
Affected topics: HTML
Modified: complete.html
===================================================================
--- complete.html 2013-07-26 22:21:58 UTC (rev 8094)
+++ complete.html 2013-07-26 23:27:44 UTC (rev 8095)
@@ -73252,7 +73252,10 @@
</dd>
- </dl><p class=note>This API does not guarantee that timers will run exactly on schedule. Delays due
+ </dl><p class=note>Timers can be nested; after five such nested timers, however, the interval is
+ forced to be at least four milliseconds.</p>
+
+ <p class=note>This API does not guarantee that timers will run exactly on schedule. Delays due
to CPU load, other tasks, etc, are to be expected.</p>
<div class=impl>
@@ -73264,229 +73267,230 @@
timers</dfn>. Each entry in this lists is identified by a number, which must be unique within the
list for the lifetime of the object that implements the <code><a href=#windowtimers>WindowTimers</a></code> interface.</p>
- <hr><p>The <dfn id=dom-windowtimers-settimeout title=dom-windowtimers-setTimeout><code>setTimeout()</code></dfn> method must run
- the following steps:
+ <hr><p>The <dfn id=dom-windowtimers-settimeout title=dom-windowtimers-setTimeout><code>setTimeout()</code></dfn> method must return
+ the value returned by the <a href=#timer-initialization-steps>timer initialization steps</a>, passing them the method's
+ arguments, the object on which the method for which the algorithm is running is implemented (a
+ <code><a href=#window>Window</a></code> or <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object) as the <var title="">method
+ context</var>, and the <var title="">repeat</var> flag set to false.</p>
- <ol><li><p>Let <var title="">handle</var> be a user-agent-defined integer that is greater than zero
- that will identify the timeout to be set by this call in the <a href=#list-of-active-timers>list of active
- timers</a>.</li>
+ <p>The <dfn id=dom-windowtimers-setinterval title=dom-windowtimers-setInterval><code>setInterval()</code></dfn> method must
+ return the value returned by the <a href=#timer-initialization-steps>timer initialization steps</a>, passing them the
+ method's arguments, the object on which the method for which the algorithm is running is
+ implemented (a <code><a href=#window>Window</a></code> or <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object) as the <var title="">method context</var>, and the <var title="">repeat</var> flag set to true.</p>
- <li><p>Add an entry to the <a href=#list-of-active-timers>list of active timers</a> for <var title="">handle</var>.</li>
+ <p>The <dfn id=dom-windowtimers-cleartimeout title=dom-windowtimers-clearTimeout><code>clearTimeout()</code></dfn> and <dfn id=dom-windowtimers-clearinterval title=dom-windowtimers-clearInterval><code>clearInterval()</code></dfn> methods must clear the
+ entry identified as <var title="">handle</var> from the <a href=#list-of-active-timers>list of active timers</a> of the
+ <code><a href=#windowtimers>WindowTimers</a></code> object on which the method was invoked, where <var title="">handle</var>
+ is the argument passed to the method, if any. (If <var title="">handle</var> does not identify an
+ entry in the <a href=#list-of-active-timers>list of active timers</a> of the <code><a href=#windowtimers>WindowTimers</a></code> object on which
+ the method was invoked, the method does nothing.)</p>
- <li><p><a href=#get-the-timed-task>Get the timed task</a> <var title="">handle</var> in the <a href=#list-of-active-timers>list of active
- timers</a>, and let <var title="">task</var> be the result. This algorithm uses the first
- argument to the method (<var title="">handler</var>) and, if there are any, the third and
- subsequent arguments to the method (<var title="">arguments</var>), to establish precisely what
- <var title="">task</var> does.</li>
+ <hr><p>The <dfn id=timer-initialization-steps>timer initialization steps</dfn>, which are invoked with some method arguments, a <var title="">method context</var>, a <var title="">repeat</var> flag which can be true or false, and
+ optionally (and only if the <var title="">repeat</var> flag is true) a <var title="">previous
+ handle</var>, are as follows:</p>
- <li><p>Let <var title="">timeout</var> be the second argument to the method, or zero if the
- argument was omitted.</li>
+ <ol><li><p>Let <var title="">method context proxy</var> be <var title="">method context</var> if that
+ is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, or else the <code><a href=#windowproxy>WindowProxy</a></code> that corresponds
+ to <var title="">method context</var>.</li>
- <li><p>If the currently running <a href=#concept-task title=concept-task>task</a> is a task that was created
- by the <code title=dom-windowtimers-setTimeout><a href=#dom-windowtimers-settimeout>setTimeout()</a></code> method, and <var title="">timeout</var> is less than 4, then increase <var title="">timeout</var> to 4.</li>
+ <li><p>If <var title="">previous handle</var> was provided, let <var title="">handle</var> be
+ <var title="">previous handle</var>; otherwise, let <var title="">handle</var> be a
+ user-agent-defined integer that is greater than zero that will identify the timeout to be set by
+ this call in the <a href=#list-of-active-timers>list of active timers</a>.</li>
- <li><p>Return <var title="">handle</var>, and then continue running this algorithm
- asynchronously.</li>
+ <li><p>If <var title="">previous handle</var> was not provided, add an entry to the <a href=#list-of-active-timers>list of
+ active timers</a> for <var title="">handle</var>.</li>
<li>
- <p>If the <a href=#method-context>method context</a> is a <code><a href=#window>Window</a></code> object, wait until the
- <code><a href=#document>Document</a></code> associated with the <a href=#method-context>method context</a> has been <a href=#fully-active>fully
- active</a> for a further <var title="">timeout</var> milliseconds (not necessarily
- consecutively).</p>
+ <p>Let <var title="">task</var> be a <a href=#concept-task title=concept-task>task</a> that runs the
+ following substeps:</p>
- <p>Otherwise, if the <a href=#method-context>method context</a> is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object,
- wait until <var title="">timeout</var> milliseconds have passed with the worker not suspended
- (not necessarily consecutively).</p>
+ <ol><li>
- <p>Otherwise, act as described in the specification that defines that the
- <code><a href=#windowtimers>WindowTimers</a></code> interface is implemented by some other object.</p>
+ <p>If the entry for <var title="">handle</var> in the <a href=#list-of-active-timers>list of active timers</a> has
+ been cleared, then abort this <a href=#concept-task title=concept-task>task</a>'s substeps.</p>
- </li>
+ </li>
- <li>
+ <li>
- <p>Wait until any invocations of this algorithm that had the same <a href=#method-context>method context</a>,
- that started before this one, and whose <var title="">timeout</var> is equal to or less than
- this one's, have completed.</p>
+ <p>Run the appropriate set of steps from the following list:</p>
- <p class=note>Argument conversion as defined by Web IDL (for example, invoking <code title="">toString()</code> methods on objects passed as the first argument) happens in the
- algorithms defined in Web IDL, before this algorithm is invoked.</p>
+ <dl class=switch><dt>If the first method argument is a <code>Function</code></dt>
- <div class=example>
+ <dd>
- <p>So for example, the following rather silly code will result in the log containing "<code title="">ONE TWO </code>":</p>
+ <p>Call the <code>Function</code>. Use the third and subsequent method arguments (if any) as
+ the arguments for invoking the <code>Function</code>. Use <var title="">method context
+ proxy</var> as the <var title="">thisArg</var> for invoking the <code>Function</code>. <a href=#refsECMA262>[ECMA262]</a></p>
- <pre>var log = '';
-function logger(s) { log += s + ' '; }
+ </dd>
-setTimeout({ toString: function () {
- setTimeout("logger('ONE')", 100);
- return "logger('TWO')";
-} }, 100);</pre>
+ <dt>Otherwise</dt>
- </div>
+ <dd>
- </li>
+ <ol><li><p>Let <var title="">script source</var> be the first method argument.</li>
- <li>
+ <li><p>Let <var title="">script language</var> be JavaScript.</li>
- <p>Optionally, wait a further user-agent defined length of time.</p>
+ <li>
- <p class=note>This is intended to allow user agents to pad timeouts as needed to optimise the
- power usage of the device. For example, some processors have a low-power mode where the
- granularity of timers is reduced; on such platforms, user agents can slow timers down to fit
- this schedule instead of requiring the processor to use the more accurate mode with its
- associated higher power usage.</p>
+ <p>If <var title="">method context</var> is a <code><a href=#window>Window</a></code> object, let <var title="">global object</var> be <var title="">method context</var>, let <var title="">browsing context</var> be the <a href=#browsing-context>browsing context</a> with which <var title="">global object</var> is associated, let <var title="">document</var> and <var title="">referrer source</var> be the <code><a href=#document>Document</a></code> associated with <var title="">global object</var>, let <var title="">character encoding</var> be the <a href="#document's-character-encoding" title="document's character encoding">character encoding</a> of the <code><a href=#document>Document</a></code>
+ associated with <var title="">global object</var> (<a href=#sce-not-copy>this is a
+ reference, not a copy</a>), and let <var title="">base URL</var> be the <a href=#document-base-url title="document base URL">base URL</a> of the <code><a href=#document>Document</a></code> associated with <var title="">global object</var> (<a href=#sbu-not-copy>this is a reference, not a
+ copy</a>).</p>
- </li>
+ <p>Otherwise, <var title="">method context</var> is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object;
+ let <var title="">global object</var>, <var title="">browsing context</var>, <var title="">document</var>, <var title="">referrer source</var>, <var title="">character
+ encoding</var>, and <var title="">base URL</var> be the <a href="#script's-global-object">script's global object</a>,
+ <a href="#script's-browsing-context">script's browsing context</a>, <a href="#script's-document">script's document</a>, <a href="#script's-referrer-source">script's
+ referrer source</a>, <a href="#script's-url-character-encoding">script's URL character encoding</a>, and <a href="#script's-base-url">script's
+ base URL</a> (respectively) of the <a href=#concept-script title=concept-script>script</a> that the
+ <a href=#run-a-worker>run a worker</a> algorithm created when it created <var title="">method
+ context</var>.</p>
- <li>
+ </li>
- <p><a href=#queue-a-task title="queue a task">Queue</a> the <a href=#concept-task title=concept-task>task</a> <var title="">task</var>.</p>
+ <li>
- <p class=note>Once the task has been processed, it is safe to remove the entry for <var title="">handle</var> from the <a href=#list-of-active-timers>list of active timers</a> (there is no way for the
- entry's existence to be detected past this point, so it does not technically matter one way or
- the other).</p>
+ <p><a href=#create-a-script>Create a script</a> using <var title="">script source</var> as the script
+ source, the <a href=#url>URL</a> where <var title="">script source</var> can be found, <var title="">scripting language</var> as the scripting language, <var title="">global
+ object</var> as the global object, <var title="">browsing context</var> as the browsing
+ context, <var title="">document</var> as the document, <var title="">referrer source</var>
+ as the referrer source, <var title="">character encoding</var> as the URL character
+ encoding, and <var title="">base URL</var> as the base URL.</p>
- </li>
+ </li>
- </ol><hr><p>The <dfn id=dom-windowtimers-setinterval title=dom-windowtimers-setInterval><code>setInterval()</code></dfn> method must run
- the following steps:
+ </ol></dd>
- <ol><li><p>Let <var title="">handle</var> be a user-agent-defined integer that is greater than zero
- that will identify the timeout to be set by this call in the <a href=#list-of-active-timers>list of active
- timers</a>.</li>
+ </dl></li>
- <li><p>Add an entry to the <a href=#list-of-active-timers>list of active timers</a> for <var title="">handle</var>.</li>
+ <li>
- <li><p><a href=#get-the-timed-task>Get the timed task</a> <var title="">handle</var> in the <a href=#list-of-active-timers>list of active
- timers</a>, and let <var title="">task</var> be the result. This algorithm uses the first
- argument to the method (<var title="">handler</var>) and, if there are any, the third and
- subsequent arguments to the method (<var title="">arguments</var>), to establish precisely what
- <var title="">task</var> does.</li>
+ <p>If the <var title="">repeat</var> flag is true, then call <a href=#timer-initialization-steps>timer initialization
+ steps</a> again, passing them the same method arguments, the same <var title="">method
+ context</var>, with the <var title="">repeat</var> flag still set to true, and with the <var title="">previous handle</var> set to <var title="">handler</var>.</p>
- <li><p>Let <var title="">timeout</var> be the second argument to the method, or zero if the
- argument was omitted.</li>
+ </li>
- <li><p>If <var title="">timeout</var> is less than 4, then increase <var title="">timeout</var>
- to 4.</li> <!-- (but see note below about IE) -->
+ </ol></li>
+ <li><p>Let <var title="">timeout</var> be the second method argument, or zero if the argument was
+ omitted.</li>
+
+ <li><p>If the currently running <a href=#concept-task title=concept-task>task</a> is a task that was created
+ by this algorithm, then let <var title="">nesting level</var> be the <a href=#concept-task title=concept-task>task</a>'s <a href=#timer-nesting-level>timer nesting level</a>. Otherwise, let <var title="">nesting level</var> be zero.</li>
+
+ <li><p>If <var title="">nesting level</var> is greater than 5, and <var title="">timeout</var> is
+ less than 4, then increase <var title="">timeout</var> to 4.</li>
+
+ <li><p>Increment <var title="">nesting level</var> by one.</li>
+
+ <li><p>Let <var title="">task</var>'s <dfn id=timer-nesting-level>timer nesting level</dfn> be <var title="">nesting
+ level</var>.</li>
+
<li><p>Return <var title="">handle</var>, and then continue running this algorithm
asynchronously.</li>
- <!-- Note: IE doesn't actually run intervals with duration zero, it aborts roughly here in the
- algorithm for them. -->
-
<li>
- <p><i title="">Wait</i>: If the <a href=#method-context>method context</a> is a <code><a href=#window>Window</a></code> object,
- wait until the <code><a href=#document>Document</a></code> associated with the <a href=#method-context>method context</a> has been
- <a href=#fully-active>fully active</a> for a further <var title="">interval</var> milliseconds (not
- necessarily consecutively).</p>
+ <p>If <var title="">method context</var> is a <code><a href=#window>Window</a></code> object, wait until the
+ <code><a href=#document>Document</a></code> associated with <var title="">method context</var> has been <a href=#fully-active>fully
+ active</a> for a further <var title="">timeout</var> milliseconds (not necessarily
+ consecutively).</p>
- <p>Otherwise, if the <a href=#method-context>method context</a> is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object,
- wait until <var title="">interval</var> milliseconds have passed with the worker not suspended
+ <p>Otherwise, <var title="">method context</var> is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object;
+ wait until <var title="">timeout</var> milliseconds have passed with the worker not suspended
(not necessarily consecutively).</p>
- <p>Otherwise, act as described in the specification that defines that the
- <code><a href=#windowtimers>WindowTimers</a></code> interface is implemented by some other object.</p>
-
</li>
<li>
- <p>Optionally, wait a further user-agent defined length of time.</p>
+ <p>Wait until any invocations of this algorithm that had the same <var title="">method
+ context</var>, that started before this one, and whose <var title="">timeout</var> is equal to
+ or less than this one's, have completed.</p>
- <p class=note>This is intended to allow user agents to pad timeouts as needed to optimise the
- power usage of the device. For example, some processors have a low-power mode where the
- granularity of timers is reduced; on such platforms, user agents can slow timers down to fit
- this schedule instead of requiring the processor to use the more accurate mode with its
- associated higher power usage.</p>
+ <p class=note>Argument conversion as defined by Web IDL (for example, invoking <code title="">toString()</code> methods on objects passed as the first argument) happens in the
+ algorithms defined in Web IDL, before this algorithm is invoked.</p>
- </li>
+ <div class=example>
- <li><p><a href=#queue-a-task title="queue a task">Queue</a> the <var title="">task</var> <a href=#concept-task title=concept-task>task</a>.</li>
+ <p>So for example, the following rather silly code will result in the log containing "<code title="">ONE TWO </code>":</p>
- <li><p>Return to the step labeled <i>wait</i>.</li>
+ <pre>var log = '';
+function logger(s) { log += s + ' '; }
- </ol><hr><p>The <dfn id=dom-windowtimers-cleartimeout title=dom-windowtimers-clearTimeout><code>clearTimeout()</code></dfn> and <dfn id=dom-windowtimers-clearinterval title=dom-windowtimers-clearInterval><code>clearInterval()</code></dfn> methods must clear the
- entry identified as <var title="">handle</var> from the <a href=#list-of-active-timers>list of active timers</a> of the
- <code><a href=#windowtimers>WindowTimers</a></code> object on which the method was invoked, where <var title="">handle</var>
- is the argument passed to the method, if any. (If <var title="">handle</var> does not identify an
- entry in the <a href=#list-of-active-timers>list of active timers</a> of the <code><a href=#windowtimers>WindowTimers</a></code> object on which
- the method was invoked, the method does nothing.)</p>
+setTimeout({ toString: function () {
+ setTimeout("logger('ONE')", 100);
+ return "logger('TWO')";
+} }, 100);</pre>
- <hr><p>The <dfn id=method-context>method context</dfn>, when referenced by the algorithms in this section, is the object
- on which the method for which the algorithm is running is implemented (a <code><a href=#window>Window</a></code> or
- <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object). The <dfn id=method-context-proxy>method context proxy</dfn> is the <a href=#method-context>method
- context</a> if that is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, or else the
- <code><a href=#windowproxy>WindowProxy</a></code> that corresponds to the <a href=#method-context>method context</a>.</p>
+ </div>
- <p>When the above methods are invoked and try to <dfn id=get-the-timed-task>get the timed task</dfn> <var title="">handle</var> in list <var title="">list</var>, they must run the following steps:</p>
+ </li>
- <ol><li>
+ <li>
- <p>If the first argument to the invoked method is a <code>Function</code>, then return a <a href=#concept-task title=concept-task>task</a> that runs the following substeps, and then abort these steps:
+ <p>Optionally, wait a further user-agent defined length of time.</p>
- <ol><li><p>If the entry for <var title="">handle</var> in <var title="">list</var> has been
- cleared, then abort this <a href=#concept-task title=concept-task>task</a>'s substeps.</li>
+ <p class=note>This is intended to allow user agents to pad timeouts as needed to optimise the
+ power usage of the device. For example, some processors have a low-power mode where the
+ granularity of timers is reduced; on such platforms, user agents can slow timers down to fit
+ this schedule instead of requiring the processor to use the more accurate mode with its
+ associated higher power usage.</p>
- <li>
+ </li>
- <p>Call the <code>Function</code>. Use the third and subsequent arguments to the invoked
- method (if any) as the arguments for invoking the <code>Function</code>. Use the <a href=#method-context-proxy>method
- context proxy</a> as the <var title="">thisArg</var> for invoking the
- <code>Function</code>. <a href=#refsECMA262>[ECMA262]</a></p>
+ <li>
- </li>
+ <p><a href=#queue-a-task title="queue a task">Queue</a> the <a href=#concept-task title=concept-task>task</a> <var title="">task</var>.</p>
- </ol><p>Otherwise, continue with the remaining steps.</p>
+ <p class=note>Once the task has been processed, if the <var title="">repeat</var> flag is
+ false, it is safe to remove the entry for <var title="">handle</var> from the <a href=#list-of-active-timers>list of
+ active timers</a> (there is no way for the entry's existence to be detected past this point,
+ so it does not technically matter one way or the other).</p>
</li>
- <li><p>Let <var title="">script source</var> be the first argument to the method.</li>
+ </ol><p>The <a href=#task-source>task source</a> for these <a href=#concept-task title=concept-task>tasks</a> is the
+ <dfn id=timer-task-source>timer task source</dfn>.</p>
- <li><p>Let <var title="">script language</var> be JavaScript.</li>
+ </div>
- <li>
+ <div class=example>
- <p>If the <a href=#method-context>method context</a> is a <code><a href=#window>Window</a></code> object, let <var title="">global
- object</var> be the <a href=#method-context>method context</a>, let <var title="">browsing context</var> be the
- <a href=#browsing-context>browsing context</a> with which <var title="">global object</var> is associated, let
- <var title="">document</var> and <var title="">referrer source</var> be the
- <code><a href=#document>Document</a></code> associated with <var title="">global object</var>, let <var title="">character encoding</var> be the <a href="#document's-character-encoding" title="document's character encoding">character
- encoding</a> of the <code><a href=#document>Document</a></code> associated with <var title="">global object</var>
- (<a href=#sce-not-copy>this is a reference, not a copy</a>), and let <var title="">base
- URL</var> be the <a href=#document-base-url title="document base URL">base URL</a> of the <code><a href=#document>Document</a></code>
- associated with <var title="">global object</var> (<a href=#sbu-not-copy>this is a reference,
- not a copy</a>).</p>
+ <p>To run tasks of several milliseconds back to back without any delay, while still yielding back
+ to the browser to avoid starving the user interface (and to avoid the browser killing the script
+ for hogging the CPU), simply queue the next timer before performing work:</p>
- <p>Otherwise, if the <a href=#method-context>method context</a> is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, let
- <var title="">global object</var>, <var title="">browsing context</var>, <var title="">document</var>, <var title="">referrer source</var>, <var title="">character
- encoding</var>, and <var title="">base URL</var> be the <a href="#script's-global-object">script's global object</a>,
- <a href="#script's-browsing-context">script's browsing context</a>, <a href="#script's-document">script's document</a>, <a href="#script's-referrer-source">script's referrer
- source</a>, <a href="#script's-url-character-encoding">script's URL character encoding</a>, and <a href="#script's-base-url">script's base URL</a>
- (respectively) of the <a href=#concept-script title=concept-script>script</a> that the <a href=#run-a-worker>run a
- worker</a> algorithm created when it created the <a href=#method-context>method context</a>.</p>
+ <pre>function doExpensiveWork() {
+ var done = false;
+ // ...
+ // this part of the function takes up to five milliseconds
+ // set done to true if we're done
+ // ...
+ return done;
+}
- <p>Otherwise, act as described in the specification that defines that the
- <code><a href=#windowtimers>WindowTimers</a></code> interface is implemented by some other object.</p>
+function rescheduleWork() {
+ var handle = setTimeout(rescheduleWork, 0); // preschedule next iteration
+ if (doExpensiveWork())
+ clearTimeout(handle); // clear the timeout if we don't need it
+}
- </li>
+function scheduleWork() {
+ setTimeout(rescheduleWork, 0);
+}
- <li><p>Return a <a href=#concept-task title=concept-task>task</a> that checks if the entry for <var title="">handle</var> in <var title="">list</var> has been cleared, and if it has not, <a href=#create-a-script title="create a script">creates a script</a> using <var title="">script source</var> as the
- script source, the <a href=#url>URL</a> where <var title="">script source</var> can be found, <var title="">scripting language</var> as the scripting language, <var title="">global object</var> as
- the global object, <var title="">browsing context</var> as the browsing context, <var title="">document</var> as the document, <var title="">referrer source</var> as the referrer
- source, <var title="">character encoding</var> as the URL character encoding, and <var title="">base URL</var> as the base URL.</li>
+scheduleWork(); // queues a task to do lots of work</pre>
- </ol><hr><p>The <a href=#task-source>task source</a> for these <a href=#concept-task title=concept-task>tasks</a> is the
- <dfn id=timer-task-source>timer task source</dfn>.</p>
-
</div>
-
<h3 id=user-prompts><span class=secno>7.4 </span>User prompts</h3>
<!--
Modified: index
===================================================================
--- index 2013-07-26 22:21:58 UTC (rev 8094)
+++ index 2013-07-26 23:27:44 UTC (rev 8095)
@@ -73252,7 +73252,10 @@
</dd>
- </dl><p class=note>This API does not guarantee that timers will run exactly on schedule. Delays due
+ </dl><p class=note>Timers can be nested; after five such nested timers, however, the interval is
+ forced to be at least four milliseconds.</p>
+
+ <p class=note>This API does not guarantee that timers will run exactly on schedule. Delays due
to CPU load, other tasks, etc, are to be expected.</p>
<div class=impl>
@@ -73264,229 +73267,230 @@
timers</dfn>. Each entry in this lists is identified by a number, which must be unique within the
list for the lifetime of the object that implements the <code><a href=#windowtimers>WindowTimers</a></code> interface.</p>
- <hr><p>The <dfn id=dom-windowtimers-settimeout title=dom-windowtimers-setTimeout><code>setTimeout()</code></dfn> method must run
- the following steps:
+ <hr><p>The <dfn id=dom-windowtimers-settimeout title=dom-windowtimers-setTimeout><code>setTimeout()</code></dfn> method must return
+ the value returned by the <a href=#timer-initialization-steps>timer initialization steps</a>, passing them the method's
+ arguments, the object on which the method for which the algorithm is running is implemented (a
+ <code><a href=#window>Window</a></code> or <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object) as the <var title="">method
+ context</var>, and the <var title="">repeat</var> flag set to false.</p>
- <ol><li><p>Let <var title="">handle</var> be a user-agent-defined integer that is greater than zero
- that will identify the timeout to be set by this call in the <a href=#list-of-active-timers>list of active
- timers</a>.</li>
+ <p>The <dfn id=dom-windowtimers-setinterval title=dom-windowtimers-setInterval><code>setInterval()</code></dfn> method must
+ return the value returned by the <a href=#timer-initialization-steps>timer initialization steps</a>, passing them the
+ method's arguments, the object on which the method for which the algorithm is running is
+ implemented (a <code><a href=#window>Window</a></code> or <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object) as the <var title="">method context</var>, and the <var title="">repeat</var> flag set to true.</p>
- <li><p>Add an entry to the <a href=#list-of-active-timers>list of active timers</a> for <var title="">handle</var>.</li>
+ <p>The <dfn id=dom-windowtimers-cleartimeout title=dom-windowtimers-clearTimeout><code>clearTimeout()</code></dfn> and <dfn id=dom-windowtimers-clearinterval title=dom-windowtimers-clearInterval><code>clearInterval()</code></dfn> methods must clear the
+ entry identified as <var title="">handle</var> from the <a href=#list-of-active-timers>list of active timers</a> of the
+ <code><a href=#windowtimers>WindowTimers</a></code> object on which the method was invoked, where <var title="">handle</var>
+ is the argument passed to the method, if any. (If <var title="">handle</var> does not identify an
+ entry in the <a href=#list-of-active-timers>list of active timers</a> of the <code><a href=#windowtimers>WindowTimers</a></code> object on which
+ the method was invoked, the method does nothing.)</p>
- <li><p><a href=#get-the-timed-task>Get the timed task</a> <var title="">handle</var> in the <a href=#list-of-active-timers>list of active
- timers</a>, and let <var title="">task</var> be the result. This algorithm uses the first
- argument to the method (<var title="">handler</var>) and, if there are any, the third and
- subsequent arguments to the method (<var title="">arguments</var>), to establish precisely what
- <var title="">task</var> does.</li>
+ <hr><p>The <dfn id=timer-initialization-steps>timer initialization steps</dfn>, which are invoked with some method arguments, a <var title="">method context</var>, a <var title="">repeat</var> flag which can be true or false, and
+ optionally (and only if the <var title="">repeat</var> flag is true) a <var title="">previous
+ handle</var>, are as follows:</p>
- <li><p>Let <var title="">timeout</var> be the second argument to the method, or zero if the
- argument was omitted.</li>
+ <ol><li><p>Let <var title="">method context proxy</var> be <var title="">method context</var> if that
+ is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, or else the <code><a href=#windowproxy>WindowProxy</a></code> that corresponds
+ to <var title="">method context</var>.</li>
- <li><p>If the currently running <a href=#concept-task title=concept-task>task</a> is a task that was created
- by the <code title=dom-windowtimers-setTimeout><a href=#dom-windowtimers-settimeout>setTimeout()</a></code> method, and <var title="">timeout</var> is less than 4, then increase <var title="">timeout</var> to 4.</li>
+ <li><p>If <var title="">previous handle</var> was provided, let <var title="">handle</var> be
+ <var title="">previous handle</var>; otherwise, let <var title="">handle</var> be a
+ user-agent-defined integer that is greater than zero that will identify the timeout to be set by
+ this call in the <a href=#list-of-active-timers>list of active timers</a>.</li>
- <li><p>Return <var title="">handle</var>, and then continue running this algorithm
- asynchronously.</li>
+ <li><p>If <var title="">previous handle</var> was not provided, add an entry to the <a href=#list-of-active-timers>list of
+ active timers</a> for <var title="">handle</var>.</li>
<li>
- <p>If the <a href=#method-context>method context</a> is a <code><a href=#window>Window</a></code> object, wait until the
- <code><a href=#document>Document</a></code> associated with the <a href=#method-context>method context</a> has been <a href=#fully-active>fully
- active</a> for a further <var title="">timeout</var> milliseconds (not necessarily
- consecutively).</p>
+ <p>Let <var title="">task</var> be a <a href=#concept-task title=concept-task>task</a> that runs the
+ following substeps:</p>
- <p>Otherwise, if the <a href=#method-context>method context</a> is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object,
- wait until <var title="">timeout</var> milliseconds have passed with the worker not suspended
- (not necessarily consecutively).</p>
+ <ol><li>
- <p>Otherwise, act as described in the specification that defines that the
- <code><a href=#windowtimers>WindowTimers</a></code> interface is implemented by some other object.</p>
+ <p>If the entry for <var title="">handle</var> in the <a href=#list-of-active-timers>list of active timers</a> has
+ been cleared, then abort this <a href=#concept-task title=concept-task>task</a>'s substeps.</p>
- </li>
+ </li>
- <li>
+ <li>
- <p>Wait until any invocations of this algorithm that had the same <a href=#method-context>method context</a>,
- that started before this one, and whose <var title="">timeout</var> is equal to or less than
- this one's, have completed.</p>
+ <p>Run the appropriate set of steps from the following list:</p>
- <p class=note>Argument conversion as defined by Web IDL (for example, invoking <code title="">toString()</code> methods on objects passed as the first argument) happens in the
- algorithms defined in Web IDL, before this algorithm is invoked.</p>
+ <dl class=switch><dt>If the first method argument is a <code>Function</code></dt>
- <div class=example>
+ <dd>
- <p>So for example, the following rather silly code will result in the log containing "<code title="">ONE TWO </code>":</p>
+ <p>Call the <code>Function</code>. Use the third and subsequent method arguments (if any) as
+ the arguments for invoking the <code>Function</code>. Use <var title="">method context
+ proxy</var> as the <var title="">thisArg</var> for invoking the <code>Function</code>. <a href=#refsECMA262>[ECMA262]</a></p>
- <pre>var log = '';
-function logger(s) { log += s + ' '; }
+ </dd>
-setTimeout({ toString: function () {
- setTimeout("logger('ONE')", 100);
- return "logger('TWO')";
-} }, 100);</pre>
+ <dt>Otherwise</dt>
- </div>
+ <dd>
- </li>
+ <ol><li><p>Let <var title="">script source</var> be the first method argument.</li>
- <li>
+ <li><p>Let <var title="">script language</var> be JavaScript.</li>
- <p>Optionally, wait a further user-agent defined length of time.</p>
+ <li>
- <p class=note>This is intended to allow user agents to pad timeouts as needed to optimise the
- power usage of the device. For example, some processors have a low-power mode where the
- granularity of timers is reduced; on such platforms, user agents can slow timers down to fit
- this schedule instead of requiring the processor to use the more accurate mode with its
- associated higher power usage.</p>
+ <p>If <var title="">method context</var> is a <code><a href=#window>Window</a></code> object, let <var title="">global object</var> be <var title="">method context</var>, let <var title="">browsing context</var> be the <a href=#browsing-context>browsing context</a> with which <var title="">global object</var> is associated, let <var title="">document</var> and <var title="">referrer source</var> be the <code><a href=#document>Document</a></code> associated with <var title="">global object</var>, let <var title="">character encoding</var> be the <a href="#document's-character-encoding" title="document's character encoding">character encoding</a> of the <code><a href=#document>Document</a></code>
+ associated with <var title="">global object</var> (<a href=#sce-not-copy>this is a
+ reference, not a copy</a>), and let <var title="">base URL</var> be the <a href=#document-base-url title="document base URL">base URL</a> of the <code><a href=#document>Document</a></code> associated with <var title="">global object</var> (<a href=#sbu-not-copy>this is a reference, not a
+ copy</a>).</p>
- </li>
+ <p>Otherwise, <var title="">method context</var> is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object;
+ let <var title="">global object</var>, <var title="">browsing context</var>, <var title="">document</var>, <var title="">referrer source</var>, <var title="">character
+ encoding</var>, and <var title="">base URL</var> be the <a href="#script's-global-object">script's global object</a>,
+ <a href="#script's-browsing-context">script's browsing context</a>, <a href="#script's-document">script's document</a>, <a href="#script's-referrer-source">script's
+ referrer source</a>, <a href="#script's-url-character-encoding">script's URL character encoding</a>, and <a href="#script's-base-url">script's
+ base URL</a> (respectively) of the <a href=#concept-script title=concept-script>script</a> that the
+ <a href=#run-a-worker>run a worker</a> algorithm created when it created <var title="">method
+ context</var>.</p>
- <li>
+ </li>
- <p><a href=#queue-a-task title="queue a task">Queue</a> the <a href=#concept-task title=concept-task>task</a> <var title="">task</var>.</p>
+ <li>
- <p class=note>Once the task has been processed, it is safe to remove the entry for <var title="">handle</var> from the <a href=#list-of-active-timers>list of active timers</a> (there is no way for the
- entry's existence to be detected past this point, so it does not technically matter one way or
- the other).</p>
+ <p><a href=#create-a-script>Create a script</a> using <var title="">script source</var> as the script
+ source, the <a href=#url>URL</a> where <var title="">script source</var> can be found, <var title="">scripting language</var> as the scripting language, <var title="">global
+ object</var> as the global object, <var title="">browsing context</var> as the browsing
+ context, <var title="">document</var> as the document, <var title="">referrer source</var>
+ as the referrer source, <var title="">character encoding</var> as the URL character
+ encoding, and <var title="">base URL</var> as the base URL.</p>
- </li>
+ </li>
- </ol><hr><p>The <dfn id=dom-windowtimers-setinterval title=dom-windowtimers-setInterval><code>setInterval()</code></dfn> method must run
- the following steps:
+ </ol></dd>
- <ol><li><p>Let <var title="">handle</var> be a user-agent-defined integer that is greater than zero
- that will identify the timeout to be set by this call in the <a href=#list-of-active-timers>list of active
- timers</a>.</li>
+ </dl></li>
- <li><p>Add an entry to the <a href=#list-of-active-timers>list of active timers</a> for <var title="">handle</var>.</li>
+ <li>
- <li><p><a href=#get-the-timed-task>Get the timed task</a> <var title="">handle</var> in the <a href=#list-of-active-timers>list of active
- timers</a>, and let <var title="">task</var> be the result. This algorithm uses the first
- argument to the method (<var title="">handler</var>) and, if there are any, the third and
- subsequent arguments to the method (<var title="">arguments</var>), to establish precisely what
- <var title="">task</var> does.</li>
+ <p>If the <var title="">repeat</var> flag is true, then call <a href=#timer-initialization-steps>timer initialization
+ steps</a> again, passing them the same method arguments, the same <var title="">method
+ context</var>, with the <var title="">repeat</var> flag still set to true, and with the <var title="">previous handle</var> set to <var title="">handler</var>.</p>
- <li><p>Let <var title="">timeout</var> be the second argument to the method, or zero if the
- argument was omitted.</li>
+ </li>
- <li><p>If <var title="">timeout</var> is less than 4, then increase <var title="">timeout</var>
- to 4.</li> <!-- (but see note below about IE) -->
+ </ol></li>
+ <li><p>Let <var title="">timeout</var> be the second method argument, or zero if the argument was
+ omitted.</li>
+
+ <li><p>If the currently running <a href=#concept-task title=concept-task>task</a> is a task that was created
+ by this algorithm, then let <var title="">nesting level</var> be the <a href=#concept-task title=concept-task>task</a>'s <a href=#timer-nesting-level>timer nesting level</a>. Otherwise, let <var title="">nesting level</var> be zero.</li>
+
+ <li><p>If <var title="">nesting level</var> is greater than 5, and <var title="">timeout</var> is
+ less than 4, then increase <var title="">timeout</var> to 4.</li>
+
+ <li><p>Increment <var title="">nesting level</var> by one.</li>
+
+ <li><p>Let <var title="">task</var>'s <dfn id=timer-nesting-level>timer nesting level</dfn> be <var title="">nesting
+ level</var>.</li>
+
<li><p>Return <var title="">handle</var>, and then continue running this algorithm
asynchronously.</li>
- <!-- Note: IE doesn't actually run intervals with duration zero, it aborts roughly here in the
- algorithm for them. -->
-
<li>
- <p><i title="">Wait</i>: If the <a href=#method-context>method context</a> is a <code><a href=#window>Window</a></code> object,
- wait until the <code><a href=#document>Document</a></code> associated with the <a href=#method-context>method context</a> has been
- <a href=#fully-active>fully active</a> for a further <var title="">interval</var> milliseconds (not
- necessarily consecutively).</p>
+ <p>If <var title="">method context</var> is a <code><a href=#window>Window</a></code> object, wait until the
+ <code><a href=#document>Document</a></code> associated with <var title="">method context</var> has been <a href=#fully-active>fully
+ active</a> for a further <var title="">timeout</var> milliseconds (not necessarily
+ consecutively).</p>
- <p>Otherwise, if the <a href=#method-context>method context</a> is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object,
- wait until <var title="">interval</var> milliseconds have passed with the worker not suspended
+ <p>Otherwise, <var title="">method context</var> is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object;
+ wait until <var title="">timeout</var> milliseconds have passed with the worker not suspended
(not necessarily consecutively).</p>
- <p>Otherwise, act as described in the specification that defines that the
- <code><a href=#windowtimers>WindowTimers</a></code> interface is implemented by some other object.</p>
-
</li>
<li>
- <p>Optionally, wait a further user-agent defined length of time.</p>
+ <p>Wait until any invocations of this algorithm that had the same <var title="">method
+ context</var>, that started before this one, and whose <var title="">timeout</var> is equal to
+ or less than this one's, have completed.</p>
- <p class=note>This is intended to allow user agents to pad timeouts as needed to optimise the
- power usage of the device. For example, some processors have a low-power mode where the
- granularity of timers is reduced; on such platforms, user agents can slow timers down to fit
- this schedule instead of requiring the processor to use the more accurate mode with its
- associated higher power usage.</p>
+ <p class=note>Argument conversion as defined by Web IDL (for example, invoking <code title="">toString()</code> methods on objects passed as the first argument) happens in the
+ algorithms defined in Web IDL, before this algorithm is invoked.</p>
- </li>
+ <div class=example>
- <li><p><a href=#queue-a-task title="queue a task">Queue</a> the <var title="">task</var> <a href=#concept-task title=concept-task>task</a>.</li>
+ <p>So for example, the following rather silly code will result in the log containing "<code title="">ONE TWO </code>":</p>
- <li><p>Return to the step labeled <i>wait</i>.</li>
+ <pre>var log = '';
+function logger(s) { log += s + ' '; }
- </ol><hr><p>The <dfn id=dom-windowtimers-cleartimeout title=dom-windowtimers-clearTimeout><code>clearTimeout()</code></dfn> and <dfn id=dom-windowtimers-clearinterval title=dom-windowtimers-clearInterval><code>clearInterval()</code></dfn> methods must clear the
- entry identified as <var title="">handle</var> from the <a href=#list-of-active-timers>list of active timers</a> of the
- <code><a href=#windowtimers>WindowTimers</a></code> object on which the method was invoked, where <var title="">handle</var>
- is the argument passed to the method, if any. (If <var title="">handle</var> does not identify an
- entry in the <a href=#list-of-active-timers>list of active timers</a> of the <code><a href=#windowtimers>WindowTimers</a></code> object on which
- the method was invoked, the method does nothing.)</p>
+setTimeout({ toString: function () {
+ setTimeout("logger('ONE')", 100);
+ return "logger('TWO')";
+} }, 100);</pre>
- <hr><p>The <dfn id=method-context>method context</dfn>, when referenced by the algorithms in this section, is the object
- on which the method for which the algorithm is running is implemented (a <code><a href=#window>Window</a></code> or
- <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object). The <dfn id=method-context-proxy>method context proxy</dfn> is the <a href=#method-context>method
- context</a> if that is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, or else the
- <code><a href=#windowproxy>WindowProxy</a></code> that corresponds to the <a href=#method-context>method context</a>.</p>
+ </div>
- <p>When the above methods are invoked and try to <dfn id=get-the-timed-task>get the timed task</dfn> <var title="">handle</var> in list <var title="">list</var>, they must run the following steps:</p>
+ </li>
- <ol><li>
+ <li>
- <p>If the first argument to the invoked method is a <code>Function</code>, then return a <a href=#concept-task title=concept-task>task</a> that runs the following substeps, and then abort these steps:
+ <p>Optionally, wait a further user-agent defined length of time.</p>
- <ol><li><p>If the entry for <var title="">handle</var> in <var title="">list</var> has been
- cleared, then abort this <a href=#concept-task title=concept-task>task</a>'s substeps.</li>
+ <p class=note>This is intended to allow user agents to pad timeouts as needed to optimise the
+ power usage of the device. For example, some processors have a low-power mode where the
+ granularity of timers is reduced; on such platforms, user agents can slow timers down to fit
+ this schedule instead of requiring the processor to use the more accurate mode with its
+ associated higher power usage.</p>
- <li>
+ </li>
- <p>Call the <code>Function</code>. Use the third and subsequent arguments to the invoked
- method (if any) as the arguments for invoking the <code>Function</code>. Use the <a href=#method-context-proxy>method
- context proxy</a> as the <var title="">thisArg</var> for invoking the
- <code>Function</code>. <a href=#refsECMA262>[ECMA262]</a></p>
+ <li>
- </li>
+ <p><a href=#queue-a-task title="queue a task">Queue</a> the <a href=#concept-task title=concept-task>task</a> <var title="">task</var>.</p>
- </ol><p>Otherwise, continue with the remaining steps.</p>
+ <p class=note>Once the task has been processed, if the <var title="">repeat</var> flag is
+ false, it is safe to remove the entry for <var title="">handle</var> from the <a href=#list-of-active-timers>list of
+ active timers</a> (there is no way for the entry's existence to be detected past this point,
+ so it does not technically matter one way or the other).</p>
</li>
- <li><p>Let <var title="">script source</var> be the first argument to the method.</li>
+ </ol><p>The <a href=#task-source>task source</a> for these <a href=#concept-task title=concept-task>tasks</a> is the
+ <dfn id=timer-task-source>timer task source</dfn>.</p>
- <li><p>Let <var title="">script language</var> be JavaScript.</li>
+ </div>
- <li>
+ <div class=example>
- <p>If the <a href=#method-context>method context</a> is a <code><a href=#window>Window</a></code> object, let <var title="">global
- object</var> be the <a href=#method-context>method context</a>, let <var title="">browsing context</var> be the
- <a href=#browsing-context>browsing context</a> with which <var title="">global object</var> is associated, let
- <var title="">document</var> and <var title="">referrer source</var> be the
- <code><a href=#document>Document</a></code> associated with <var title="">global object</var>, let <var title="">character encoding</var> be the <a href="#document's-character-encoding" title="document's character encoding">character
- encoding</a> of the <code><a href=#document>Document</a></code> associated with <var title="">global object</var>
- (<a href=#sce-not-copy>this is a reference, not a copy</a>), and let <var title="">base
- URL</var> be the <a href=#document-base-url title="document base URL">base URL</a> of the <code><a href=#document>Document</a></code>
- associated with <var title="">global object</var> (<a href=#sbu-not-copy>this is a reference,
- not a copy</a>).</p>
+ <p>To run tasks of several milliseconds back to back without any delay, while still yielding back
+ to the browser to avoid starving the user interface (and to avoid the browser killing the script
+ for hogging the CPU), simply queue the next timer before performing work:</p>
- <p>Otherwise, if the <a href=#method-context>method context</a> is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, let
- <var title="">global object</var>, <var title="">browsing context</var>, <var title="">document</var>, <var title="">referrer source</var>, <var title="">character
- encoding</var>, and <var title="">base URL</var> be the <a href="#script's-global-object">script's global object</a>,
- <a href="#script's-browsing-context">script's browsing context</a>, <a href="#script's-document">script's document</a>, <a href="#script's-referrer-source">script's referrer
- source</a>, <a href="#script's-url-character-encoding">script's URL character encoding</a>, and <a href="#script's-base-url">script's base URL</a>
- (respectively) of the <a href=#concept-script title=concept-script>script</a> that the <a href=#run-a-worker>run a
- worker</a> algorithm created when it created the <a href=#method-context>method context</a>.</p>
+ <pre>function doExpensiveWork() {
+ var done = false;
+ // ...
+ // this part of the function takes up to five milliseconds
+ // set done to true if we're done
+ // ...
+ return done;
+}
- <p>Otherwise, act as described in the specification that defines that the
- <code><a href=#windowtimers>WindowTimers</a></code> interface is implemented by some other object.</p>
+function rescheduleWork() {
+ var handle = setTimeout(rescheduleWork, 0); // preschedule next iteration
+ if (doExpensiveWork())
+ clearTimeout(handle); // clear the timeout if we don't need it
+}
- </li>
+function scheduleWork() {
+ setTimeout(rescheduleWork, 0);
+}
- <li><p>Return a <a href=#concept-task title=concept-task>task</a> that checks if the entry for <var title="">handle</var> in <var title="">list</var> has been cleared, and if it has not, <a href=#create-a-script title="create a script">creates a script</a> using <var title="">script source</var> as the
- script source, the <a href=#url>URL</a> where <var title="">script source</var> can be found, <var title="">scripting language</var> as the scripting language, <var title="">global object</var> as
- the global object, <var title="">browsing context</var> as the browsing context, <var title="">document</var> as the document, <var title="">referrer source</var> as the referrer
- source, <var title="">character encoding</var> as the URL character encoding, and <var title="">base URL</var> as the base URL.</li>
+scheduleWork(); // queues a task to do lots of work</pre>
- </ol><hr><p>The <a href=#task-source>task source</a> for these <a href=#concept-task title=concept-task>tasks</a> is the
- <dfn id=timer-task-source>timer task source</dfn>.</p>
-
</div>
-
<h3 id=user-prompts><span class=secno>7.4 </span>User prompts</h3>
<!--
Modified: source
===================================================================
--- source 2013-07-26 22:21:58 UTC (rev 8094)
+++ source 2013-07-26 23:27:44 UTC (rev 8095)
@@ -81983,6 +81983,9 @@
</dl>
+ <p class="note">Timers can be nested; after five such nested timers, however, the interval is
+ forced to be at least four milliseconds.</p>
+
<p class="note">This API does not guarantee that timers will run exactly on schedule. Delays due
to CPU load, other tasks, etc, are to be expected.</p>
@@ -81997,271 +82000,268 @@
<hr>
- <p>The <dfn title="dom-windowtimers-setTimeout"><code>setTimeout()</code></dfn> method must run
- the following steps:
+ <p>The <dfn title="dom-windowtimers-setTimeout"><code>setTimeout()</code></dfn> method must return
+ the value returned by the <span>timer initialization steps</span>, passing them the method's
+ arguments, the object on which the method for which the algorithm is running is implemented (a
+ <code>Window</code> or <code>WorkerGlobalScope</code> object) as the <var title="">method
+ context</var>, and the <var title="">repeat</var> flag set to false.</p>
- <ol>
+ <p>The <dfn title="dom-windowtimers-setInterval"><code>setInterval()</code></dfn> method must
+ return the value returned by the <span>timer initialization steps</span>, passing them the
+ method's arguments, the object on which the method for which the algorithm is running is
+ implemented (a <code>Window</code> or <code>WorkerGlobalScope</code> object) as the <var
+ title="">method context</var>, and the <var title="">repeat</var> flag set to true.</p>
- <li><p>Let <var title="">handle</var> be a user-agent-defined integer that is greater than zero
- that will identify the timeout to be set by this call in the <span>list of active
- timers</span>.</p></li>
+ <p>The <dfn title="dom-windowtimers-clearTimeout"><code>clearTimeout()</code></dfn> and <dfn
+ title="dom-windowtimers-clearInterval"><code>clearInterval()</code></dfn> methods must clear the
+ entry identified as <var title="">handle</var> from the <span>list of active timers</span> of the
+ <code>WindowTimers</code> object on which the method was invoked, where <var title="">handle</var>
+ is the argument passed to the method, if any. (If <var title="">handle</var> does not identify an
+ entry in the <span>list of active timers</span> of the <code>WindowTimers</code> object on which
+ the method was invoked, the method does nothing.)</p>
- <li><p>Add an entry to the <span>list of active timers</span> for <var
- title="">handle</var>.</p></li>
+ <hr>
- <li><p><span>Get the timed task</span> <var title="">handle</var> in the <span>list of active
- timers</span>, and let <var title="">task</var> be the result. This algorithm uses the first
- argument to the method (<var title="">handler</var>) and, if there are any, the third and
- subsequent arguments to the method (<var title="">arguments</var>), to establish precisely what
- <var title="">task</var> does.</p></li>
+ <p>The <dfn>timer initialization steps</dfn>, which are invoked with some method arguments, a <var
+ title="">method context</var>, a <var title="">repeat</var> flag which can be true or false, and
+ optionally (and only if the <var title="">repeat</var> flag is true) a <var title="">previous
+ handle</var>, are as follows:</p>
- <li><p>Let <var title="">timeout</var> be the second argument to the method, or zero if the
- argument was omitted.</p></li>
+ <ol>
- <li><p>If the currently running <span title="concept-task">task</span> is a task that was created
- by the <code title="dom-windowtimers-setTimeout">setTimeout()</code> method, and <var
- title="">timeout</var> is less than 4, then increase <var title="">timeout</var> to 4.</p></li>
+ <li><p>Let <var title="">method context proxy</var> be <var title="">method context</var> if that
+ is a <code>WorkerGlobalScope</code> object, or else the <code>WindowProxy</code> that corresponds
+ to <var title="">method context</var>.</p></li>
- <li><p>Return <var title="">handle</var>, and then continue running this algorithm
- asynchronously.</p></li>
+ <li><p>If <var title="">previous handle</var> was provided, let <var title="">handle</var> be
+ <var title="">previous handle</var>; otherwise, let <var title="">handle</var> be a
+ user-agent-defined integer that is greater than zero that will identify the timeout to be set by
+ this call in the <span>list of active timers</span>.</p></li>
+ <li><p>If <var title="">previous handle</var> was not provided, add an entry to the <span>list of
+ active timers</span> for <var title="">handle</var>.</p></li>
+
<li>
- <p>If the <span>method context</span> is a <code>Window</code> object, wait until the
- <code>Document</code> associated with the <span>method context</span> has been <span>fully
- active</span> for a further <var title="">timeout</var> milliseconds (not necessarily
- consecutively).</p>
+ <p>Let <var title="">task</var> be a <span title="concept-task">task</span> that runs the
+ following substeps:</p>
- <p>Otherwise, if the <span>method context</span> is a <code>WorkerGlobalScope</code> object,
- wait until <var title="">timeout</var> milliseconds have passed with the worker not suspended
- (not necessarily consecutively).</p>
+ <ol>
- <p>Otherwise, act as described in the specification that defines that the
- <code>WindowTimers</code> interface is implemented by some other object.</p>
+ <li>
- </li>
+ <p>If the entry for <var title="">handle</var> in the <span>list of active timers</span> has
+ been cleared, then abort this <span title="concept-task">task</span>'s substeps.</p>
- <li>
+ </li>
- <p>Wait until any invocations of this algorithm that had the same <span>method context</span>,
- that started before this one, and whose <var title="">timeout</var> is equal to or less than
- this one's, have completed.</p>
+ <li>
- <p class="note">Argument conversion as defined by Web IDL (for example, invoking <code
- title="">toString()</code> methods on objects passed as the first argument) happens in the
- algorithms defined in Web IDL, before this algorithm is invoked.</p>
+ <p>Run the appropriate set of steps from the following list:</p>
- <div class="example">
+ <dl class="switch">
- <p>So for example, the following rather silly code will result in the log containing "<code
- title="">ONE TWO </code>":</p>
+ <dt>If the first method argument is a <code>Function</code></dt>
- <pre>var log = '';
-function logger(s) { log += s + ' '; }
+ <dd>
-setTimeout({ toString: function () {
- setTimeout("logger('ONE')", 100);
- return "logger('TWO')";
-} }, 100);</pre>
+ <p>Call the <code>Function</code>. Use the third and subsequent method arguments (if any) as
+ the arguments for invoking the <code>Function</code>. Use <var title="">method context
+ proxy</var> as the <var title="">thisArg</var> for invoking the <code>Function</code>. <a
+ href="#refsECMA262">[ECMA262]</a></p>
- </div>
+ </dd>
- </li>
+ <dt>Otherwise</dt>
- <li>
+ <dd>
- <p>Optionally, wait a further user-agent defined length of time.</p>
+ <ol>
- <p class="note">This is intended to allow user agents to pad timeouts as needed to optimise the
- power usage of the device. For example, some processors have a low-power mode where the
- granularity of timers is reduced; on such platforms, user agents can slow timers down to fit
- this schedule instead of requiring the processor to use the more accurate mode with its
- associated higher power usage.</p>
+ <li><p>Let <var title="">script source</var> be the first method argument.</p></li>
- </li>
+ <li><p>Let <var title="">script language</var> be JavaScript.</p></li>
- <li>
+ <li>
- <p><span title="queue a task">Queue</span> the <span title="concept-task">task</span> <var
- title="">task</var>.</p>
+ <p>If <var title="">method context</var> is a <code>Window</code> object, let <var
+ title="">global object</var> be <var title="">method context</var>, let <var
+ title="">browsing context</var> be the <span>browsing context</span> with which <var
+ title="">global object</var> is associated, let <var title="">document</var> and <var
+ title="">referrer source</var> be the <code>Document</code> associated with <var
+ title="">global object</var>, let <var title="">character encoding</var> be the <span
+ title="document's character encoding">character encoding</span> of the <code>Document</code>
+ associated with <var title="">global object</var> (<a href="#sce-not-copy">this is a
+ reference, not a copy</a>), and let <var title="">base URL</var> be the <span
+ title="document base URL">base URL</span> of the <code>Document</code> associated with <var
+ title="">global object</var> (<a href="#sbu-not-copy">this is a reference, not a
+ copy</a>).</p>
- <p class="note">Once the task has been processed, it is safe to remove the entry for <var
- title="">handle</var> from the <span>list of active timers</span> (there is no way for the
- entry's existence to be detected past this point, so it does not technically matter one way or
- the other).</p>
+ <p>Otherwise, <var title="">method context</var> is a <code>WorkerGlobalScope</code> object;
+ let <var title="">global object</var>, <var title="">browsing context</var>, <var
+ title="">document</var>, <var title="">referrer source</var>, <var title="">character
+ encoding</var>, and <var title="">base URL</var> be the <span>script's global object</span>,
+ <span>script's browsing context</span>, <span>script's document</span>, <span>script's
+ referrer source</span>, <span>script's URL character encoding</span>, and <span>script's
+ base URL</span> (respectively) of the <span title="concept-script">script</span> that the
+ <span>run a worker</span> algorithm created when it created <var title="">method
+ context</var>.</p>
- </li>
+ </li>
- </ol>
+ <li>
- <hr>
+ <p><span>Create a script</span> using <var title="">script source</var> as the script
+ source, the <span>URL</span> where <var title="">script source</var> can be found, <var
+ title="">scripting language</var> as the scripting language, <var title="">global
+ object</var> as the global object, <var title="">browsing context</var> as the browsing
+ context, <var title="">document</var> as the document, <var title="">referrer source</var>
+ as the referrer source, <var title="">character encoding</var> as the URL character
+ encoding, and <var title="">base URL</var> as the base URL.</p>
- <p>The <dfn title="dom-windowtimers-setInterval"><code>setInterval()</code></dfn> method must run
- the following steps:
+ </li>
- <ol>
+ </ol>
- <li><p>Let <var title="">handle</var> be a user-agent-defined integer that is greater than zero
- that will identify the timeout to be set by this call in the <span>list of active
- timers</span>.</p></li>
+ </dd>
- <li><p>Add an entry to the <span>list of active timers</span> for <var
- title="">handle</var>.</p></li>
+ </dl>
- <li><p><span>Get the timed task</span> <var title="">handle</var> in the <span>list of active
- timers</span>, and let <var title="">task</var> be the result. This algorithm uses the first
- argument to the method (<var title="">handler</var>) and, if there are any, the third and
- subsequent arguments to the method (<var title="">arguments</var>), to establish precisely what
- <var title="">task</var> does.</p></li>
+ </li>
- <li><p>Let <var title="">timeout</var> be the second argument to the method, or zero if the
- argument was omitted.</p></li>
+ <li>
- <li><p>If <var title="">timeout</var> is less than 4, then increase <var title="">timeout</var>
- to 4.</p></li> <!-- (but see note below about IE) -->
+ <p>If the <var title="">repeat</var> flag is true, then call <span>timer initialization
+ steps</span> again, passing them the same method arguments, the same <var title="">method
+ context</var>, with the <var title="">repeat</var> flag still set to true, and with the <var
+ title="">previous handle</var> set to <var title="">handler</var>.</p>
- <li><p>Return <var title="">handle</var>, and then continue running this algorithm
- asynchronously.</p></li>
+ </li>
- <!-- Note: IE doesn't actually run intervals with duration zero, it aborts roughly here in the
- algorithm for them. -->
+ </ol>
- <li>
+ </li>
- <p><i title="">Wait</i>: If the <span>method context</span> is a <code>Window</code> object,
- wait until the <code>Document</code> associated with the <span>method context</span> has been
- <span>fully active</span> for a further <var title="">interval</var> milliseconds (not
- necessarily consecutively).</p>
+ <li><p>Let <var title="">timeout</var> be the second method argument, or zero if the argument was
+ omitted.</p></li>
- <p>Otherwise, if the <span>method context</span> is a <code>WorkerGlobalScope</code> object,
- wait until <var title="">interval</var> milliseconds have passed with the worker not suspended
- (not necessarily consecutively).</p>
+ <li><p>If the currently running <span title="concept-task">task</span> is a task that was created
+ by this algorithm, then let <var title="">nesting level</var> be the <span
+ title="concept-task">task</span>'s <span>timer nesting level</span>. Otherwise, let <var
+ title="">nesting level</var> be zero.</p></li>
- <p>Otherwise, act as described in the specification that defines that the
- <code>WindowTimers</code> interface is implemented by some other object.</p>
+ <li><p>If <var title="">nesting level</var> is greater than 5, and <var title="">timeout</var> is
+ less than 4, then increase <var title="">timeout</var> to 4.</p></li>
- </li>
+ <li><p>Increment <var title="">nesting level</var> by one.</p></li>
+ <li><p>Let <var title="">task</var>'s <dfn>timer nesting level</dfn> be <var title="">nesting
+ level</var>.</p></li>
+
+ <li><p>Return <var title="">handle</var>, and then continue running this algorithm
+ asynchronously.</p></li>
+
<li>
- <p>Optionally, wait a further user-agent defined length of time.</p>
+ <p>If <var title="">method context</var> is a <code>Window</code> object, wait until the
+ <code>Document</code> associated with <var title="">method context</var> has been <span>fully
+ active</span> for a further <var title="">timeout</var> milliseconds (not necessarily
+ consecutively).</p>
- <p class="note">This is intended to allow user agents to pad timeouts as needed to optimise the
- power usage of the device. For example, some processors have a low-power mode where the
- granularity of timers is reduced; on such platforms, user agents can slow timers down to fit
- this schedule instead of requiring the processor to use the more accurate mode with its
- associated higher power usage.</p>
+ <p>Otherwise, <var title="">method context</var> is a <code>WorkerGlobalScope</code> object;
+ wait until <var title="">timeout</var> milliseconds have passed with the worker not suspended
+ (not necessarily consecutively).</p>
</li>
- <li><p><span title="queue a task">Queue</span> the <var title="">task</var> <span
- title="concept-task">task</span>.</p></li>
+ <li>
- <li><p>Return to the step labeled <i>wait</i>.</p></li>
+ <p>Wait until any invocations of this algorithm that had the same <var title="">method
+ context</var>, that started before this one, and whose <var title="">timeout</var> is equal to
+ or less than this one's, have completed.</p>
- </ol>
+ <p class="note">Argument conversion as defined by Web IDL (for example, invoking <code
+ title="">toString()</code> methods on objects passed as the first argument) happens in the
+ algorithms defined in Web IDL, before this algorithm is invoked.</p>
- <hr>
+ <div class="example">
- <p>The <dfn title="dom-windowtimers-clearTimeout"><code>clearTimeout()</code></dfn> and <dfn
- title="dom-windowtimers-clearInterval"><code>clearInterval()</code></dfn> methods must clear the
- entry identified as <var title="">handle</var> from the <span>list of active timers</span> of the
- <code>WindowTimers</code> object on which the method was invoked, where <var title="">handle</var>
- is the argument passed to the method, if any. (If <var title="">handle</var> does not identify an
- entry in the <span>list of active timers</span> of the <code>WindowTimers</code> object on which
- the method was invoked, the method does nothing.)</p>
+ <p>So for example, the following rather silly code will result in the log containing "<code
+ title="">ONE TWO </code>":</p>
- <hr>
+ <pre>var log = '';
+function logger(s) { log += s + ' '; }
- <p>The <dfn>method context</dfn>, when referenced by the algorithms in this section, is the object
- on which the method for which the algorithm is running is implemented (a <code>Window</code> or
- <code>WorkerGlobalScope</code> object). The <dfn>method context proxy</dfn> is the <span>method
- context</span> if that is a <code>WorkerGlobalScope</code> object, or else the
- <code>WindowProxy</code> that corresponds to the <span>method context</span>.</p>
+setTimeout({ toString: function () {
+ setTimeout("logger('ONE')", 100);
+ return "logger('TWO')";
+} }, 100);</pre>
- <p>When the above methods are invoked and try to <dfn>get the timed task</dfn> <var
- title="">handle</var> in list <var title="">list</var>, they must run the following steps:</p>
+ </div>
- <ol>
+ </li>
<li>
- <p>If the first argument to the invoked method is a <code>Function</code>, then return a <span
- title="concept-task">task</span> that runs the following substeps, and then abort these steps:
+ <p>Optionally, wait a further user-agent defined length of time.</p>
- <ol>
+ <p class="note">This is intended to allow user agents to pad timeouts as needed to optimise the
+ power usage of the device. For example, some processors have a low-power mode where the
+ granularity of timers is reduced; on such platforms, user agents can slow timers down to fit
+ this schedule instead of requiring the processor to use the more accurate mode with its
+ associated higher power usage.</p>
- <li><p>If the entry for <var title="">handle</var> in <var title="">list</var> has been
- cleared, then abort this <span title="concept-task">task</span>'s substeps.</p></li>
+ </li>
- <li>
+ <li>
- <p>Call the <code>Function</code>. Use the third and subsequent arguments to the invoked
- method (if any) as the arguments for invoking the <code>Function</code>. Use the <span>method
- context proxy</span> as the <var title="">thisArg</var> for invoking the
- <code>Function</code>. <a href="#refsECMA262">[ECMA262]</a></p>
+ <p><span title="queue a task">Queue</span> the <span title="concept-task">task</span> <var
+ title="">task</var>.</p>
- </li>
+ <p class="note">Once the task has been processed, if the <var title="">repeat</var> flag is
+ false, it is safe to remove the entry for <var title="">handle</var> from the <span>list of
+ active timers</span> (there is no way for the entry's existence to be detected past this point,
+ so it does not technically matter one way or the other).</p>
- </ol>
-
- <p>Otherwise, continue with the remaining steps.</p>
-
</li>
- <li><p>Let <var title="">script source</var> be the first argument to the method.</p></li>
+ </ol>
- <li><p>Let <var title="">script language</var> be JavaScript.</p></li>
+ <p>The <span>task source</span> for these <span title="concept-task">tasks</span> is the
+ <dfn>timer task source</dfn>.</p>
- <li>
+ </div>
- <p>If the <span>method context</span> is a <code>Window</code> object, let <var title="">global
- object</var> be the <span>method context</span>, let <var title="">browsing context</var> be the
- <span>browsing context</span> with which <var title="">global object</var> is associated, let
- <var title="">document</var> and <var title="">referrer source</var> be the
- <code>Document</code> associated with <var title="">global object</var>, let <var
- title="">character encoding</var> be the <span title="document's character encoding">character
- encoding</span> of the <code>Document</code> associated with <var title="">global object</var>
- (<a href="#sce-not-copy">this is a reference, not a copy</a>), and let <var title="">base
- URL</var> be the <span title="document base URL">base URL</span> of the <code>Document</code>
- associated with <var title="">global object</var> (<a href="#sbu-not-copy">this is a reference,
- not a copy</a>).</p>
+ <div class="example">
- <p>Otherwise, if the <span>method context</span> is a <code>WorkerGlobalScope</code> object, let
- <var title="">global object</var>, <var title="">browsing context</var>, <var
- title="">document</var>, <var title="">referrer source</var>, <var title="">character
- encoding</var>, and <var title="">base URL</var> be the <span>script's global object</span>,
- <span>script's browsing context</span>, <span>script's document</span>, <span>script's referrer
- source</span>, <span>script's URL character encoding</span>, and <span>script's base URL</span>
- (respectively) of the <span title="concept-script">script</span> that the <span>run a
- worker</span> algorithm created when it created the <span>method context</span>.</p>
+ <p>To run tasks of several milliseconds back to back without any delay, while still yielding back
+ to the browser to avoid starving the user interface (and to avoid the browser killing the script
+ for hogging the CPU), simply queue the next timer before performing work:</p>
- <p>Otherwise, act as described in the specification that defines that the
- <code>WindowTimers</code> interface is implemented by some other object.</p>
+ <pre>function doExpensiveWork() {
+ var done = false;
+ // ...
+ // this part of the function takes up to five milliseconds
+ // set done to true if we're done
+ // ...
+ return done;
+}
- </li>
+function rescheduleWork() {
+ var handle = setTimeout(rescheduleWork, 0); // preschedule next iteration
+ if (doExpensiveWork())
+ clearTimeout(handle); // clear the timeout if we don't need it
+}
- <li><p>Return a <span title="concept-task">task</span> that checks if the entry for <var
- title="">handle</var> in <var title="">list</var> has been cleared, and if it has not, <span
- title="create a script">creates a script</span> using <var title="">script source</var> as the
- script source, the <span>URL</span> where <var title="">script source</var> can be found, <var
- title="">scripting language</var> as the scripting language, <var title="">global object</var> as
- the global object, <var title="">browsing context</var> as the browsing context, <var
- title="">document</var> as the document, <var title="">referrer source</var> as the referrer
- source, <var title="">character encoding</var> as the URL character encoding, and <var
- title="">base URL</var> as the base URL.</p></li>
+function scheduleWork() {
+ setTimeout(rescheduleWork, 0);
+}
- </ol>
+scheduleWork(); // queues a task to do lots of work</pre>
- <hr>
-
- <p>The <span>task source</span> for these <span title="concept-task">tasks</span> is the
- <dfn>timer task source</dfn>.</p>
-
</div>
-
<h3>User prompts</h3>
<!--
More information about the Commit-Watchers
mailing list