src/cm/media/js/lib/yui/yui_3.10.3/docs/async-queue/index.html
changeset 525 89ef5ed3c48b
equal deleted inserted replaced
524:322d0feea350 525:89ef5ed3c48b
       
     1 <!DOCTYPE html>
       
     2 <html lang="en">
       
     3 <head>
       
     4     <meta charset="utf-8">
       
     5     <title>AsyncQueue</title>
       
     6     <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=PT+Sans:400,700,400italic,700italic">
       
     7     <link rel="stylesheet" href="../../build/cssgrids/cssgrids-min.css">
       
     8     <link rel="stylesheet" href="../assets/css/main.css">
       
     9     <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
       
    10     <link rel="shortcut icon" type="image/png" href="../assets/favicon.png">
       
    11     <script src="../../build/yui/yui-min.js"></script>
       
    12     
       
    13 </head>
       
    14 <body>
       
    15 <!--
       
    16 <a href="https://github.com/yui/yui3"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a>
       
    17 -->
       
    18 <div id="doc">
       
    19     <div id="hd">
       
    20         <h1><img src="http://yuilibrary.com/img/yui-logo.png"></h1>
       
    21     </div>
       
    22     
       
    23         <a href="#toc" class="jump">Jump to Table of Contents</a>
       
    24     
       
    25 
       
    26             <h1>AsyncQueue</h1>
       
    27     <div class="yui3-g">
       
    28         <div class="yui3-u-3-4">
       
    29             <div id="main">
       
    30                 <div class="content"><div class="intro" class="component">
       
    31     <p>
       
    32         AsyncQueue allows you create a chain of function callbacks executed via
       
    33         <code>setTimeout</code> that are guaranteed to run in order.  This can
       
    34         enable progressive incremental rendering of your UI so your users can
       
    35         begin to see and interact with your page while the infrastructure is
       
    36         being built.  Similarly, process-intensive operations that will lock up
       
    37         the UI while the JavaScript is being executed can be broken up into
       
    38         chunks, helping to keep your interface responsive.
       
    39     </p>
       
    40 </div>
       
    41 
       
    42 <h2 id="getting-started">Getting Started</h2>
       
    43 
       
    44 <p>
       
    45 To include the source files for AsyncQueue and its dependencies, first load
       
    46 the YUI seed file if you haven't already loaded it.
       
    47 </p>
       
    48 
       
    49 <pre class="code prettyprint">&lt;script src=&quot;http:&#x2F;&#x2F;yui.yahooapis.com&#x2F;3.10.3&#x2F;build&#x2F;yui&#x2F;yui-min.js&quot;&gt;&lt;&#x2F;script&gt;</pre>
       
    50 
       
    51 
       
    52 <p>
       
    53 Next, create a new YUI instance for your application and populate it with the
       
    54 modules you need by specifying them as arguments to the <code>YUI().use()</code> method.
       
    55 YUI will automatically load any dependencies required by the modules you
       
    56 specify.
       
    57 </p>
       
    58 
       
    59 <pre class="code prettyprint">&lt;script&gt;
       
    60 &#x2F;&#x2F; Create a new YUI instance and populate it with the required modules.
       
    61 YUI().use(&#x27;async-queue&#x27;, function (Y) {
       
    62     &#x2F;&#x2F; AsyncQueue is available and ready for use. Add implementation
       
    63     &#x2F;&#x2F; code here.
       
    64 });
       
    65 &lt;&#x2F;script&gt;</pre>
       
    66 
       
    67 
       
    68 <p>
       
    69 For more information on creating YUI instances and on the
       
    70 <a href="http://yuilibrary.com/yui/docs/api/classes/YUI.html#method_use"><code>use()</code> method</a>, see the
       
    71 documentation for the <a href="../yui/index.html">YUI Global Object</a>.
       
    72 </p>
       
    73 
       
    74 
       
    75 <h2 id="using">Using AsyncQueue</h2>
       
    76 
       
    77 <h3 id="interacting">Creating and interacting with an AsyncQueue</h3>
       
    78 
       
    79 <p>
       
    80     AsyncQueues manage an array of callbacks that can be either simple function
       
    81     references or <a href="#callbacks">objects with specific keys</a>.  The
       
    82     primary methods on AsyncQueue are <code>add</code> and
       
    83     <code>run</code>.
       
    84 </p>
       
    85 
       
    86 <p>
       
    87     When <code>run()</code> is invoked, each callback is executed in turn,
       
    88     either synchronously or via <code>setTimeout</code> (depending on the
       
    89     configuration of the callback or of the AsyncQueue instance).
       
    90 </p>
       
    91 
       
    92 <p>
       
    93     Queued callbacks can also be promoted to the top of the queue or removed
       
    94     from it.
       
    95 </p>
       
    96 
       
    97 <pre class="code prettyprint">var q = new Y.AsyncQueue(callbackB, someTask, callbackA, callbackC);
       
    98 q.add(callbackD, callbackE); &#x2F;&#x2F; B, someTask, A, C, D, E
       
    99 q.promote(callbackA);        &#x2F;&#x2F; A, B, someTask, C, D, E
       
   100 q.remove(someTask);          &#x2F;&#x2F; A, B, C, D, E
       
   101 q.run();                     &#x2F;&#x2F; execute A, then B, then C, then D, then E</pre>
       
   102 
       
   103 
       
   104 
       
   105 <h4 id="stopping">Pausing and stopping an AsyncQueue</h4>
       
   106 
       
   107 <p>
       
   108     In addition to <code>run()</code>, AsyncQueue instances also have
       
   109     <code>pause()</code> and <code>stop()</code> methods to interrupt the run
       
   110     state.
       
   111 </p>
       
   112 
       
   113 <p>
       
   114     To wait for an external process to complete, such as an XHR request, call
       
   115     <code>pause()</code>, then <code>run()</code> again to resume
       
   116     execution.
       
   117 </p>
       
   118                 
       
   119 <p>
       
   120     Call <code>stop()</code> to terminate execution and flush the AsyncQueue.
       
   121 </p>
       
   122 
       
   123 <pre class="code prettyprint">&#x2F;&#x2F; Seed the instance with callbacks
       
   124 var q = new Y.AsyncQueue(
       
   125     MyApp.doSomething,
       
   126 
       
   127     &#x2F;&#x2F; The second callback will pause the Queue and send an XHR for data
       
   128     function () {
       
   129         q.pause();
       
   130 
       
   131         &#x2F;&#x2F; Send the asynchronous XHR
       
   132         Y.io(MyApp.getDataUri(), { on: {
       
   133             success : function (xid,o) {
       
   134                 try {
       
   135                     var data = Y.JSON.parse(o.responseText);
       
   136                 }
       
   137                 catch (e) {
       
   138                     MyApp.showErrorStatus();
       
   139                     q.stop();
       
   140                 }
       
   141 
       
   142                 MyApp.processData(data);
       
   143 
       
   144                 &#x2F;&#x2F; In the XHR callback, restart the AsyncQueue if successful
       
   145                 q.run();
       
   146             },
       
   147             failure : function () {
       
   148                 MyApp.showErrorStatus();
       
   149                 &#x2F;&#x2F; Stop the AsyncQueue if anything goes wrong
       
   150                 q.stop();
       
   151             }
       
   152         }});
       
   153     },
       
   154 
       
   155     &#x2F;&#x2F; The third callback will do partial updates until complete
       
   156     {
       
   157         fn:    Y.bind(MyApp.updateUI,MyApp),
       
   158         until: function () {
       
   159             return MyApp.remainingData &gt;= 0;
       
   160         }
       
   161     },
       
   162     MyApp.doSomethingElse);
       
   163 
       
   164 q.run();</pre>
       
   165 
       
   166 
       
   167 
       
   168 <h4 id="callbacks">About AsyncQueue callbacks</h4>
       
   169 
       
   170 <p>
       
   171     AsyncQueue callbacks can be simple function references or object literals
       
   172     with the following keys:
       
   173 </p>
       
   174 
       
   175 <table>
       
   176 <thead>
       
   177     <tr>
       
   178         <th>property</th>
       
   179         <th>description</th>
       
   180         <th>default</th>
       
   181     </tr>
       
   182 </thead>
       
   183 <tbody>
       
   184     <tr>
       
   185         <td><code>fn</code></td>
       
   186         <td><strong>Required</strong>.  The callback function to execute.</td>
       
   187         <td>(none)</td>
       
   188     </tr>
       
   189     <tr>
       
   190         <td><code>context</code></td>
       
   191         <td>The context from which to execute the callback function.</td>
       
   192         <td>The AsyncQueue instance</td>
       
   193     </tr>
       
   194     <tr>
       
   195         <td><code>args</code></td>
       
   196         <td>Array of arguments that will be passed as individual args to the callback function.</td>
       
   197         <td>(none)</td>
       
   198     </tr>
       
   199     <tr>
       
   200         <td><code>timeout</code></td>
       
   201         <td>Millisecond delay before each execution of this callback.  Set to -1 to trigger synchronous execution.</td>
       
   202         <td>10</td>
       
   203     </tr>
       
   204     <tr>
       
   205         <td><code>iterations</code></td>
       
   206         <td>The number of times to execute this callback before shifting it from the queue.</td>
       
   207         <td>1</td>
       
   208     </tr>
       
   209     <tr>
       
   210         <td><code>until</code></td>
       
   211         <td>A function that will return <code>true</code> when the current callback can be shifted from the queue.</td>
       
   212         <td>a function that tests against <code>iterations</code></td>
       
   213     </tr>
       
   214     <tr>
       
   215         <td><code>id</code></td>
       
   216         <td>Name given to this callback for ease of reference.</td>
       
   217         <td>(none)</td>
       
   218     </tr>
       
   219     <tr>
       
   220         <td><code>autoContinue</code></td>
       
   221         <td>Set to <code>false</code> to automatically <code>pause()</code> after this callback.</td>
       
   222         <td>true</td>
       
   223     </tr>
       
   224 </tbody>
       
   225 </table>
       
   226 
       
   227 <h4 id="defaults">Class- and instance-level callback defaults</h4>
       
   228 
       
   229 <p>
       
   230     AsyncQueue provides three places to configure callbacks (in decreasing
       
   231     precedence order):
       
   232 </p>
       
   233 
       
   234 <ol>
       
   235     <li>The callback object</li>
       
   236     <li>The AsyncQueue instance's <code>defaults</code> collection</li>
       
   237     <li>The class static <code>defaults</code> collection</li>
       
   238 </ol>
       
   239 
       
   240 <pre class="code prettyprint">&#x2F;&#x2F; All AsyncQueue instances will execute all callbacks synchronously by default
       
   241 Y.AsyncQueue.defaults.timeout = -1;
       
   242 
       
   243 var q = new Y.AsyncQueue();
       
   244 
       
   245 &#x2F;&#x2F; run every callback in this instance twice before moving to the next callback
       
   246 q.defaults.iterations = 2;
       
   247 
       
   248 q.add(functionA,
       
   249       {
       
   250         fn: functionB,
       
   251         timeout: 100 &#x2F;&#x2F; this callback will be executed asynchronously
       
   252       });
       
   253 
       
   254 &#x2F;&#x2F; functionA executes twice immediately, then after 100 milliseconds functionB
       
   255 &#x2F;&#x2F; is executed, then after another 100ms functionB is executed again.
       
   256 q.run();</pre>
       
   257 
       
   258 
       
   259 
       
   260 <h4 id="sync">Synchronous mode for callback execution</h4>
       
   261 <p>
       
   262     One of the main goals of the AsyncQueue is to provide a mechanism to
       
   263     prevent process-intensive operations from locking up the UI.  By default,
       
   264     AsyncQueue callbacks are executed via <code>setTimeout</code> to facilitate
       
   265     this.  The <code>timeout</code> configuration accepts -1 as a value to
       
   266     trigger synchronous callback execution.  Use this setting with caution.
       
   267 </p>
       
   268                 
       
   269 <h4 id="chaining">About timeout chaining</h4>
       
   270 
       
   271 <p>
       
   272     Timeout chaining is a strategy to address the lack of <a
       
   273     href="http://en.wikipedia.org/wiki/Thread_(computer_science)">multithreading</a>
       
   274     in JavaScript.  When complex or iterative code executes it can cause the
       
   275     page to stop responding until the running JavaScript process completes; it
       
   276     can also cause "non-responsive script" or "long-running script" dialogs to
       
   277     be presented to the user.  Both outcomes are detrimental to user
       
   278     experience.
       
   279 </p>
       
   280 
       
   281 <p>
       
   282     To address this, the operation can be split into chunks, and
       
   283     <code>setTimeout</code> can be used to yield control back to other
       
   284     operations between each chunk.  A common use case for this technique is to
       
   285     allow browser reflows to display DOM modifications incrementally while
       
   286     batches of work are being done in JavaScript.  For iterative functions, the
       
   287     code can execute a portion of the overall work, then schedule itself to run
       
   288     via <code>setTimeout</code>.
       
   289 </p>
       
   290 
       
   291 <p>The basic form of an iterative timeout chain is:</p>
       
   292 
       
   293 <pre class="code prettyprint">(function () {
       
   294 
       
   295     &#x2F;* do a chunk of the work *&#x2F;
       
   296 
       
   297     if (&#x2F;* process completion check fails *&#x2F;) {
       
   298         &#x2F;&#x2F; Schedule myself for re-execution, picking up where I left off
       
   299         setTimeout(arguments.callee,0);
       
   300     }
       
   301 })();</pre>
       
   302 
       
   303 
       
   304 
       
   305 <p>
       
   306     When dealing with <code>setTimeout</code>, it's easy to introduce race
       
   307     conditions.  Because all timeouts are scheduled against the same timer and
       
   308     only one can run at a time, when two timeouts are separately scheduled, it
       
   309     is possible for them to execute out of intended order.
       
   310 </p>
       
   311 
       
   312 <p>
       
   313     AsyncQueue supports both "chunked operations" (by specifying callback
       
   314     timeouts) and "iterative operations" (by specifying callback
       
   315     <code>iterations</code> or <code>until</code> functions).  Furthermore,
       
   316     AsyncQueue manages the callback sequence and can therefore guarantee the
       
   317     execution order, so you avoid race conditions.
       
   318 </p>
       
   319 
       
   320 <h4 id="events">Exposed events</h4>
       
   321 <p>
       
   322     AsyncQueue is based on EventTarget and instances emit the following events
       
   323     throughout their lifecycle:
       
   324 </p>
       
   325 
       
   326 <table>
       
   327 <thead>
       
   328     <tr>
       
   329         <th>Event</th>
       
   330         <th>When</th>
       
   331         <th>Event payload</th>
       
   332     </tr>
       
   333 </thead>
       
   334 <tbody>
       
   335     <tr>
       
   336         <td><code>add</code></td>
       
   337         <td>Callbacks are added to the AsyncQueue.</td>
       
   338         <td><code>{ callbacks: (Array of callbacks added) }</code></td>
       
   339     </tr>
       
   340     <tr>
       
   341         <td><code>promote</code></td>
       
   342         <td>A callback is promoted.</td>
       
   343         <td><code>{ callback : (callback) }</code></td>
       
   344     </tr>
       
   345     <tr>
       
   346         <td><code>remove</code></td>
       
   347         <td>A callback is removed.</td>
       
   348         <td><code>{ callback : (callback) }</code></td>
       
   349     </tr>
       
   350     <tr>
       
   351         <td><code>execute</code></td>
       
   352         <td>A callback is executed.</td>
       
   353         <td><code>{ callback : (callback) }</code></td>
       
   354     </tr>
       
   355     <tr>
       
   356         <td><code>shift</code></td>
       
   357         <td>A callback is shifted from the AsyncQueue.</td>
       
   358         <td><code>{ callback : (callback) }</code></td>
       
   359     </tr>
       
   360     <tr>
       
   361         <td><code>complete</code></td>
       
   362         <td>After the last callback is finished executing.  <em>NOT</em> fired after <code>stop()</code>.</td>
       
   363         <td>(none)</td>
       
   364     </tr>
       
   365 </tbody>
       
   366 </table>
       
   367 </div>
       
   368             </div>
       
   369         </div>
       
   370 
       
   371         <div class="yui3-u-1-4">
       
   372             <div class="sidebar">
       
   373                 
       
   374                     <div id="toc" class="sidebox">
       
   375                         <div class="hd">
       
   376                             <h2 class="no-toc">Table of Contents</h2>
       
   377                         </div>
       
   378 
       
   379                         <div class="bd">
       
   380                             <ul class="toc">
       
   381 <li>
       
   382 <a href="#getting-started">Getting Started</a>
       
   383 </li>
       
   384 <li>
       
   385 <a href="#using">Using AsyncQueue</a>
       
   386 <ul class="toc">
       
   387 <li>
       
   388 <a href="#interacting">Creating and interacting with an AsyncQueue</a>
       
   389 <ul class="toc">
       
   390 <li>
       
   391 <a href="#stopping">Pausing and stopping an AsyncQueue</a>
       
   392 </li>
       
   393 <li>
       
   394 <a href="#callbacks">About AsyncQueue callbacks</a>
       
   395 </li>
       
   396 <li>
       
   397 <a href="#defaults">Class- and instance-level callback defaults</a>
       
   398 </li>
       
   399 <li>
       
   400 <a href="#sync">Synchronous mode for callback execution</a>
       
   401 </li>
       
   402 <li>
       
   403 <a href="#chaining">About timeout chaining</a>
       
   404 </li>
       
   405 <li>
       
   406 <a href="#events">Exposed events</a>
       
   407 </li>
       
   408 </ul>
       
   409 </li>
       
   410 </ul>
       
   411 </li>
       
   412 </ul>
       
   413                         </div>
       
   414                     </div>
       
   415                 
       
   416 
       
   417                 
       
   418                     <div class="sidebox">
       
   419                         <div class="hd">
       
   420                             <h2 class="no-toc">Examples</h2>
       
   421                         </div>
       
   422 
       
   423                         <div class="bd">
       
   424                             <ul class="examples">
       
   425                                 
       
   426                                     
       
   427                                         <li data-description="This example employs AsyncQueue to incrementally construct an application interface; this illustrates the approach you&#x27;d take to allow chunked rendering of the UI in a process-intensive application.">
       
   428                                             <a href="queue-app.html">Building a UI with AsyncQueue</a>
       
   429                                         </li>
       
   430                                     
       
   431                                 
       
   432                             </ul>
       
   433                         </div>
       
   434                     </div>
       
   435                 
       
   436 
       
   437                 
       
   438             </div>
       
   439         </div>
       
   440     </div>
       
   441 </div>
       
   442 
       
   443 <script src="../assets/vendor/prettify/prettify-min.js"></script>
       
   444 <script>prettyPrint();</script>
       
   445 
       
   446 <script>
       
   447 YUI.Env.Tests = {
       
   448     examples: [],
       
   449     project: '../assets',
       
   450     assets: '../assets/async-queue',
       
   451     name: 'async-queue',
       
   452     title: 'AsyncQueue',
       
   453     newWindow: '',
       
   454     auto:  false 
       
   455 };
       
   456 YUI.Env.Tests.examples.push('queue-app');
       
   457 
       
   458 </script>
       
   459 <script src="../assets/yui/test-runner.js"></script>
       
   460 
       
   461 
       
   462 
       
   463 </body>
       
   464 </html>