sequencing function calls in javascript - are callbacks the only way?

后端 未结 5 542
谎友^
谎友^ 2021-02-03 11:25

I read through various threads like this one for example.

But it really escapes me how to accomplish the following:

I have 4 functions, and want them happen one

相关标签:
5条回答
  • 2021-02-03 11:56

    I have played with the Promise, Sequence, Exception, Callback to understand how it works and finally made this code.

    Call functions with callback and send result as parameter to another function in sequence and have a catch errors.

    function firstFunction(par) {
        return new Promise(function (resolve, reject) {
            console.log("start " + par);
            setTimeout(function (par) {
                console.log(par);
                resolve(par + 1);
            }, 1000, par);
        });
    }
    function secondFunction(par) {
        return new Promise(function (resolve, reject) {
            console.log("start " + par);
            setTimeout(function (par) {
                console.log(par);
                try{
                    throw "Let's make an error...";
                }
                catch(err)
                {
                    reject(err);
                }
                resolve(par + 1);
            }, 1000, par);
        })
    }
    function thirdFunction(par) {
        return new Promise(function (resolve, reject) {
            console.log("start " + par);
            setTimeout(function (par) {
                console.log(par);
                resolve(par + 1);
            }, 1000, par);
        });
    }
    
    function CatchError(error) {
        console.log("Exception: " + error);
    }
    
    //Break all chain in second function
    function ChainBrake() {
        firstFunction(1)
        .then(secondFunction)
        .then(thirdFunction)
        .catch(CatchError);    
    }
    
    //Log error and continue executing chain
    function ChainContinue() {
        firstFunction(1)
        .catch(CatchError)
        .then(secondFunction)
        .catch(CatchError)
        .then(thirdFunction)
        .catch(CatchError);
    }
    
    0 讨论(0)
  • 2021-02-03 11:58

    If I'm using callbacks, my working solution now looks like this:

        one(two);
        function one(callb){
            console.log('1');
            callb(three);
        }
        function four(){
            console.log('4');
        }
        function two(callb){
            console.log('2');
            callb(four);
        }
        function three(callb){
            console.log('3');
            callb();
        }
    

    I find that hideous. How am I supposed to keep track of this stuff if there is more than 2-3 sequences? Shudder...

    0 讨论(0)
  • 2021-02-03 12:09

    It's a great chance to start using jQuery Deferred.

    Apart from the callbacks-based solution the code is readable, flexible and highly maintainable

    http://jsfiddle.net/zerkms/zJhph/

    function firstFunction(){
      var d = $.Deferred();
      // some very time consuming asynchronous code...
      setTimeout(function() {
        console.log('1');
        d.resolve();
      }, 1000);
      return d.promise();
    }
    function thirdFunction(){
      var d = $.Deferred();
      // definitely dont wanna do this until secondFunction is finished
      setTimeout(function() {
        console.log('3');
        d.resolve();
      }, 1000);
      return d.promise();
    }
    function secondFunction(){
      var d = $.Deferred();
      setTimeout(function() {
        console.log('2');
        d.resolve();
      }, 1000);
      return d.promise();
    }
    function fourthFunction(){
      var d = $.Deferred();
      // last function, not executed until the other 3 are done.
      setTimeout(function() {
        console.log('4');
        d.resolve();
      }, 1000);
      return d.promise();
    }
    
    firstFunction().pipe(secondFunction).pipe(thirdFunction).pipe(fourthFunction);​
    

    PS: as an example of asynchronous code I've used setTimeout. The main thing is that in the end of the asynchronous part you need to call d.resolve() to continue chaining methods.

    Further reading: http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/

    0 讨论(0)
  • 2021-02-03 12:15

    It's been a while and I noticed something about deferreds in jquery documentation, specifically the when core API function.

    $.when( $.ajax("test.aspx") ).then(function(ajaxArgs){ 
         alert(ajaxArgs[1]); /* ajaxArgs is [ "success", statusText, jqXHR ] */
    });
    

    Code sample taken from http://jqapi.com/#p=jQuery.when

    0 讨论(0)
  • 2021-02-03 12:16

    The idea is you'd do something like the following so that once the first function was done running, it'd know what to run as opposed to you having to figure it out on your own outside the function:

    function firstFunction(callback){
      // some very time consuming asynchronous code...
      console.log('1');
    
      return callback(function(){
        alert("Second function finished.");
        return true;
      });
    }
    function secondFunction(callback){
      // waits for firstFunction to be completed
      console.log('2');
    
      return callback();
    }
    
    firstFunction(secondFunction);
    

    Also look up .apply() and .call().

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