jquery custom deferred functions

后端 未结 2 1458
深忆病人
深忆病人 2021-01-31 12:12

I have three functions i\'m trying to run, the first two are doing some async stuff that need data for the third to use. I want the third function to fire only when 1 and 2 are

相关标签:
2条回答
  • 2021-01-31 12:32

    You should return promise object. You also have an error in this line:

    $.when(first(), second()).done(constructData());
    

    it should be

    $.when(first(), second()).done(constructData); // don't call constructData immediately
    

    So all together it could be:

    function run() {
        var data1 = {};
        var data2 = {};
    
        $.when(first(), second()).done(constructData);
    
        function first() {
            return $.Deferred(function() { // <-- see returning Deferred object
                var self = this;
    
                setTimeout(function() {   // <-- example of some async operation
                    data1 = {func: 'first', data: true};
                    self.resolve();       // <-- call resolve method once async is done
                }, 2000);
            });
        }
        function second() {
            return $.Deferred(function() {
                var self = this;
                setTimeout(function() {
                    data2 = {func: 'second', data: true};
                    self.resolve();
                }, 3000);
            });
        }
        function constructData() {
            //do stuff with data1 and data2
            console.log(data1, data2);
        }
    }
    

    http://jsfiddle.net/FwXZC/

    0 讨论(0)
  • 2021-01-31 12:44

    I think you should have first() and second() return a promise: return d.promise();. From the docs:

    If a single argument is passed to jQuery.when and it is not a Deferred or a Promise, it will be treated as a resolved Deferred and any doneCallbacks attached will be executed immediately.

    I suspect this might be why the when call is calling constructData too soon.

    It's hard to tell from you code, but be sure you are calling d.resolve() after the async operations have completed.

    You might find that a more natural approach to explicitly setting data1 and data2 is instead to use the data that is supplied when resolve is called. This would mean that your when call would look something like this:

    $.when(first(), second()).done(function(result1, result2) {
        data1 = result1[0];
        data2 = result2[0];
    
        constructData();
    });
    

    Note that the exact format of results supplied to the done method depends on the nature of the deferred objects. If the promises are returned from a call to $.ajax, the results should be of the form [data, statusText, jqXhrObject].

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