简体   繁体   中英

Learning Javascript/Jquery promise&deferred, issue with $.when multiple use

    //just a function to simulate, ajax etc.
    function wait () {

        var deferred = $.Deferred();
        console.log('hello')setTimeout(deferred.resolve,3000);
        return deferred.promise();
    }

    var func = function () {

        var first,before,after,resolvePromise,main;
        var beforeList = [];
        var afterList = [];
        var def = new $.Deferred();

        //push to array function
        first = function () {

            beforeList.push(wait);  
            beforeList.push(wait);
            afterList.push(wait);
            console.log('first done', beforeList,afterList)
        }

        //this must run before the main
        before = function () {

            var beforeDef = new $.Deferred();

            $.when.apply($,beforeList).done(function () {
                console.log('before', new Date().getTime())
                beforeDef.resolve();
            });

            return beforeDef.promise();
        }

        //this must run after main
        after = function () {

            var afterDef = new $.Deferred();

            $.when.apply($,afterList).done(function () {
                console.log('after', new Date().getTime())
                afterDef.resolve();
            });

            return afterDef.promise();
        }

        // this is main function
        main = function () {
            console.log('doing job in main function', new Date().getTime())
        }

        //handler
        resolvePromise = function () {
            def.resolve();
            return def.promise();
        }

        //action
        var step = def.then(first);
        var step1 = step.then(before);
        var step2 = step1.then(main);
        var step3 = step2.then(after)
        .done(function () {
            console.log('all done')
        });
        resolvePromise();
    }
func();

I am just starting to learn promise&deferred. Here is my code. My main goal is, 'creating two arrays full of function'. Which name is afterList and beforeList. I want to run those before and after my main function.

My main issue is i can't make work the lists in $.when().

The list that is passed to $.when needs to be one of promises, not one of functions that will yield them when called. You need to trigger the wait s yourself:

function first() {
    beforeList.push(wait());  
    beforeList.push(wait());
    afterList.push(wait());
    console.log('first done', beforeList,afterList)
}

Also, I wouldn't rely on that global variables beforeList / afterList . You should construct the list (and start the tasks) and apply the $.when in one single step.

And don't construct Deferreds so often ( def , beforeDef , afterDef ). The main advantage of promises is their chainability, you should not need to resolve any of them manually. Too easily you forget to handle errors and pass them on, which is automated if you simply reuse the promises or call then to pipe functions.

function before() {
    var beforeList = [];
    beforeList.push(wait());
    beforeList.push(wait());

    var beforeProm = $.when.apply($, beforeList);
    beforeProm.done(function () {
        console.log('before', new Date().getTime())
    });
    return beforeProm;
}
// same thing, coded simpler:
function after() {
    var afterList = [ wait() ];

    return $.when.apply($, afterList).done(function () {
        console.log('after', new Date().getTime())
    });
}

function main() {
    console.log('doing job in main function', new Date().getTime())
    return undefined; // the results of the main job which
                      // after needs to wait for
}

// action - without an extra "handler"
before().then(main).then(after).done(function () {
    console.log('all done')
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM