Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Since <strong>jQuery 1.8</strong> <code>.then</code> behaves the same as <code>.pipe</code>:</p> <blockquote> <p><strong>Deprecation Notice:</strong> As of jQuery 1.8, the <code>deferred.pipe()</code> method is deprecated. The <code>deferred.then()</code> method, which replaces it, should be used instead.</p> </blockquote> <p>and</p> <blockquote> <p><strong>As of jQuery 1.8</strong>, the <code>deferred.then()</code> method returns a new promise that can filter the status and values of a deferred through a function, replacing the now-deprecated <code>deferred.pipe()</code> method.</p> </blockquote> <p>The examples below might still be helpful to some.</p> <hr> <p>They serve different purposes:</p> <ul> <li><p><code>.then()</code> is to be used whenever you want to work with the result of the process, i.e. as the documentation says, when the deferred object is resolved or rejected. It is the same as using <code>.done()</code> or <code>.fail()</code>.</p></li> <li><p>You'd use <code>.pipe()</code> to (pre)<em>filter</em> the result somehow. The return value of a callback to <code>.pipe()</code> will be passed as argument to the <code>done</code> and <code>fail</code> callbacks. It can also return another deferred object and the following callbacks will be registered on this deferred.</p> <p>That is not the case with <code>.then()</code> (or <code>.done()</code>, <code>.fail()</code>), the return values of the registered callbacks are just ignored.</p></li> </ul> <p>So it is not that you use <em>either</em> <code>.then()</code> <em>or</em> <code>.pipe()</code>. You <em>could</em> use <code>.pipe()</code> for the same purposes as <code>.then()</code> but the converse does not hold.</p> <hr> <h3>Example 1</h3> <p>The result of some operation is an array of objects:</p> <pre><code>[{value: 2}, {value: 4}, {value: 6}] </code></pre> <p>and you want to compute the minimum and maximum of the values. Lets assume we use two <code>done</code> callbacks:</p> <pre><code>deferred.then(function(result) { // result = [{value: 2}, {value: 4}, {value: 6}] var values = []; for(var i = 0, len = result.length; i &lt; len; i++) { values.push(result[i].value); } var min = Math.min.apply(Math, values); /* do something with "min" */ }).then(function(result) { // result = [{value: 2}, {value: 4}, {value: 6}] var values = []; for(var i = 0, len = result.length; i &lt; len; i++) { values.push(result[i].value); } var max = Math.max.apply(Math, values); /* do something with "max" */ }); </code></pre> <p>In both cases you have to iterate over the list and extract the value from each object. </p> <p>Wouldn't it be better to somehow extract the values beforehand so that you don't have to do this in both callbacks individually? Yes! And that's what we can use <code>.pipe()</code> for:</p> <pre><code>deferred.pipe(function(result) { // result = [{value: 2}, {value: 4}, {value: 6}] var values = []; for(var i = 0, len = result.length; i &lt; len; i++) { values.push(result[i].value); } return values; // [2, 4, 6] }).then(function(result) { // result = [2, 4, 6] var min = Math.min.apply(Math, result); /* do something with "min" */ }).then(function(result) { // result = [2, 4, 6] var max = Math.max.apply(Math, result); /* do something with "max" */ }); </code></pre> <p>Obviously this is a made up example and there are many different (maybe better) ways to solve this problem, but I hope it illustrates the point.</p> <hr> <h3>Example 2</h3> <p>Consider Ajax calls. Sometimes you want to initiate one Ajax call after a previous one completes. One way is to make the second call inside a <code>done</code> callback:</p> <pre><code>$.ajax(...).done(function() { // executed after first Ajax $.ajax(...).done(function() { // executed after second call }); }); </code></pre> <p>Now lets assume you want to decouple your code and put these two Ajax calls inside a function:</p> <pre><code>function makeCalls() { // here we return the return value of `$.ajax().done()`, which // is the same deferred object as returned by `$.ajax()` alone return $.ajax(...).done(function() { // executed after first call $.ajax(...).done(function() { // executed after second call }); }); } </code></pre> <p>You'd like to use the deferred object to allow other code which calls <code>makeCalls</code> to attach callbacks for the <em>second</em> Ajax call, but</p> <pre><code>makeCalls().done(function() { // this is executed after the first Ajax call }); </code></pre> <p>would not have the desired effect as the second call is made inside a <code>done</code> callback and not accessible from the outside. </p> <p>The solution would be to use <code>.pipe()</code> instead:</p> <pre><code>function makeCalls() { // here we return the return value of `$.ajax().pipe()`, which is // a new deferred/promise object and connected to the one returned // by the callback passed to `pipe` return $.ajax(...).pipe(function() { // executed after first call return $.ajax(...).done(function() { // executed after second call }); }); } makeCalls().done(function() { // this is executed after the second Ajax call }); </code></pre> <p>By using <code>.pipe()</code> you can now make it possible to append callbacks to the "inner" Ajax call without exposing the actual flow/order of the calls.</p> <hr> <p>In general, deferred objects provide an interesting way to decouple your code :)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload