Understanding Deferred.pipe()

后端 未结 3 1827
失恋的感觉
失恋的感觉 2021-02-01 20:44

I\'ve been reading about deferreds and promises in jQuery but I haven\'t used it yet.

I\'ve understood everything very well but the method pipe. I really didn\'t get wha

相关标签:
3条回答
  • 2021-02-01 20:50

    Basically, Deferred.pipe() is an asynchronous equivalent to $.map(). It projects new values from other values provided as input, but its purpose is to be used with continuations.

    Let's start with an example that only requires $.each() and issues an AJAX request that returns a simple object. For each property of this object, we want the form control whose id attribute is the property's key to set its value to the property's value. We can write something like:

    $.ajax("your/url", {
        dataType: "json"
    }).done(function(data) {
        $.each(data, function(key, value) {
            $("#" + key).val(value);
        });
    });
    

    Now let's say we want to apply some function to the values before updating the form controls. If we do that locally, we only have to write:

    $.ajax("your/url", {
        dataType: "json"
    }).done(function(data) {
        $.each(data, function(key, value) {
            // doSomethingWith() projects values synchronously, as map() does.
            $("#" + key).val(doSomethingWith(value));
        });
    });
    

    But what happens if doSomethingWith() is not implemented client-side, but server-side through another web service? In that case, we want to chain the control flow into the second AJAX request, and only update the form controls when the second request has returned. Deferred.pipe() makes that easy:

    $.ajax("your/url", {
        dataType: "json"
    }).pipe(function(theOriginalData) {
        return $.ajax("your/web/service/doSomethingWith", {
            data: theOriginalData,
            dataType: "json"
        });
    }).done(function(theFinalData) {
        $.each(theFinalData, function(key, value) {
            $("#" + key).val(value);
        });
    });
    
    0 讨论(0)
  • 2021-02-01 20:56

    Hiya is this what you are looking for :)

    [nice read] http://www.bennadel.com/blog/2255-Using-jQuery-s-Pipe-Method-To-Change-Deferred-Resolution.htm

    quote

    The pipe() method provides a filter for both the success and failure resolutions (of the AJAX request). If the original resolution is success, the pipe() filter either passes a truly successful response through; or, it changes the resolution, returning a new rejected promise. Then, if the original request was a failure, which would be truly unexpected in our API, the pipe() filter simply passes through a normalized API response structure....

    Stack link with example Understanding jQuery Deferred.pipe() (has jsfiddle in it)

    Understanding Deferred & Promise? please see here http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/

    Jquery official API page http://api.jquery.com/deferred.pipe/ (with examples)

    Description: Utility method to filter and/or chain Deferreds.

    The deferred.pipe() method returns a new promise that filters the status and values of a deferred through a function. The doneFilter and failFilter functions filter the original deferred's resolved / rejected status and values. As of jQuery 1.7, the method also accepts a progressFilter function to filter any calls to the original deferred's notify or notifyWith methods.

    0 讨论(0)
  • 2021-02-01 21:13

    OK, I see a lot of reference material in another answer here, but reading is sometimes not the same as understanding.

    I find it easiest to think of a Promise and the application of .done() to it vs. .pipe() to it. Each one acts differently. If I take promise.done(function (result) { ... }) then I can tack on more .done()'s or .fail()'s after that because each call to .done() or .fail() returns the exact same promise. So each function will be tied to the original promise and whether it gets resolved or rejected.

    Now, contrast that to .pipe(). If I take promise.pipe(function (result) { ...}) then what comes out of the .pipe() is an all new promise! If I then attach .done() or .fail() to that promise then those functions will get the modified version of the results that the .pipe() returns, not the original results.

    So .pipe() is, in my experience, rarely necessary. The only time it really comes in handy is if you need to modify the data that is returned from a promise before other code sees it (for example, modifying some results of an AJAX call on the client side before any other client side code works with it) or if you need to sequence things. For example, after promise A resolves or rejects, take another action, and then only when that is done do we want other code to finally trigger. All of the other code is attached to the promise B that came from the .pipe() call.

    Here's a recent question where another user had problems with the use of promises and .pipe()/.done()/.when() and I tried to provide some code to clarify the use of each one in a jsFiddle: Do something when all deferreds are resolved

    0 讨论(0)
提交回复
热议问题