最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Execute Function One by One - Stack Overflow

programmeradmin4浏览0评论

I have 3 different jQuery functions like:

function step1() {
  ...
}

function step2() {
  ...
}

function step3() {
  ...
}

and if I call them like this:

step1();
step2();
step3();

they will be all executed in the same time. How can I call them one by one so step2(); is called after step1(); is finished and step3(); is called after step2(); is finished.

// MORE INFO

Step1() is executing a json and appends details to html, Step2() is executing another json and appends info in the divs created by Step1() and Step3() simply hides a loading animation.

// THE FUNCTIONS

As requested by some users, here are the functions:

jQuery.noConflict();

jQuery(document).ready(function($) {

    var cardType = $.cookie('cardType');
    var categoryID = $.cookie('categoryID');

    function step1() {
        $.getJSON('.json', function(data) {
            $.each(data, function(i,item){
                if (item.benefit_type_id == categoryID) {
                    content = '<li><a class="showDetails" data-offer-description="' + item.description + '" data-offer-period="' + item.begin_date + ' - ' + item.end_date + '"><div class="pany" title="' + item.business_id + '"></div><div class="shortdescription">' + item.name + '</div></a></li>';
                    $(content).appendTo("#thelist");
                }
            }); 
            step2();
        });
    } // function step1();

    function step2() {  
        $('pany').each(function(i, item) {
            var tempTitle = item.title;
            $.getJSON('/' + tempTitle + '.json', function(data2) {
                $.each(data2, function(i,item){
                    content = '<span>' + item.name + '</span>';
                    $(content).appendTo("div[title='" + tempTitle + "']");
                }); 
                step3();
            });
        });
    } // function step2();

    function step3() {
        loaded();
        $('#loading').delay(1000).fadeOut('slow', function() {
            // Animation plete.
        });
    } // function step3();

    step1();

});

I have 3 different jQuery functions like:

function step1() {
  ...
}

function step2() {
  ...
}

function step3() {
  ...
}

and if I call them like this:

step1();
step2();
step3();

they will be all executed in the same time. How can I call them one by one so step2(); is called after step1(); is finished and step3(); is called after step2(); is finished.

// MORE INFO

Step1() is executing a json and appends details to html, Step2() is executing another json and appends info in the divs created by Step1() and Step3() simply hides a loading animation.

// THE FUNCTIONS

As requested by some users, here are the functions:

jQuery.noConflict();

jQuery(document).ready(function($) {

    var cardType = $.cookie('cardType');
    var categoryID = $.cookie('categoryID');

    function step1() {
        $.getJSON('http://domain./benefits/active/all.json', function(data) {
            $.each(data, function(i,item){
                if (item.benefit_type_id == categoryID) {
                    content = '<li><a class="showDetails" data-offer-description="' + item.description + '" data-offer-period="' + item.begin_date + ' - ' + item.end_date + '"><div class="pany" title="' + item.business_id + '"></div><div class="shortdescription">' + item.name + '</div></a></li>';
                    $(content).appendTo("#thelist");
                }
            }); 
            step2();
        });
    } // function step1();

    function step2() {  
        $('.pany').each(function(i, item) {
            var tempTitle = item.title;
            $.getJSON('http://domain./businesses/from_list/' + tempTitle + '.json', function(data2) {
                $.each(data2, function(i,item){
                    content = '<span>' + item.name + '</span>';
                    $(content).appendTo("div[title='" + tempTitle + "']");
                }); 
                step3();
            });
        });
    } // function step2();

    function step3() {
        loaded();
        $('#loading').delay(1000).fadeOut('slow', function() {
            // Animation plete.
        });
    } // function step3();

    step1();

});
Share Improve this question edited Jan 21, 2013 at 1:05 Jeff 12.8k5 gold badges35 silver badges61 bronze badges asked Jan 20, 2013 at 23:59 Andrei RRRAndrei RRR 3,16217 gold badges47 silver badges81 bronze badges 6
  • 1 They will be executed sequentially since JavaScript is single-threaded. Or, at least what people monly make use of. Can you tell us more about what is being run in those functions? – Alexander Commented Jan 21, 2013 at 0:00
  • Step1() is executing a json and appends details to html, Step2() is executing another json and appends info in the divs created by Step1() and Step3() simply hides a loading animation. – Andrei RRR Commented Jan 21, 2013 at 0:06
  • 1 JSON cannot be executed, it's a data format. Do you mean that you are making Ajax requests? – Felix Kling Commented Jan 21, 2013 at 0:09
  • Yes, I am making ajax requests. I will update my question and post the exact functions. – Andrei RRR Commented Jan 21, 2013 at 0:15
  • possible duplicate of How to chain ajax requests? – Felix Kling Commented Jan 21, 2013 at 0:16
 |  Show 1 more ment

2 Answers 2

Reset to default 7

Not knowing what you are executing in each function, I'm assuming none of them executes an asynchronous call themselves, i.e: ajax request and so on.

Should you have additional asynchronous calls occur in each function the below would not apply as is.

One option would be to use call one from the other similar to this:

function step1() {
    //...
    step2();
}

function step2() {
    //...
    step3();
}

function step3() {
    //...
}

or you can use callbacks in the function signature, similar to this:

//pass step2 function as parameter to step1
//pass step3 function as parameter to step2
step1(step2(step3));

function step1(callback) {
    //...
    callback();
}

function step2(callback) {
    //...
    callback();
}

function step3() {
    //...
}

Or using jQuery deferred might work, similar to this:

$.when($.when(step1()).then(step2)).then(step3);

I'm not 100% sure on the deferred solution using .when().

The code above seems to work (DEMO) using when() but as FelixKing mentioned in the ments if you update the methods to return a deferred promise you can do this:

step1().then(step2).then(step3);

DEMO - Using a deferred promise


Each deferred object must be resolved() though for the next method to be executed.
This would also give you some control if you have a scenario for example in which you don't want to execute step3() if step2() fails to do something and calls .reject() for instance.

Have a play around with the deferred objects in the fiddle and have a look at the deferred promise documentation too for more details.

Sample-Code from DEMO:

step1().then(step2).then(step3);

function step1() {
    var $dfStep1 = new $.Deferred();

    console.log("step1");

    $dfStep1.resolve();
    return $dfStep1.promise();
}

function step2() {
    var $dfStep2 = new $.Deferred();

    console.log("step2");

    $dfStep2.resolve();
    return $dfStep2.promise();
}

function step3() {
    var $dfStep3 = new $.Deferred();

    console.log("step3");

    $dfStep3.resolve();
    return $dfStep3.promise();
}

If there is no asynchronous behaviour within the functions then they will be called sequentially. You may be seeing output in the console at different times than you expect, I believe consoles in firefox etc buffer output and can in some cases (although not very often) be misleading.

If you do have asynchronous behaviour within these functions then you either need to make it synchronous or put the call to function2 in the callback to function1 and function3 in the callback to function2. This will ensure that function2 is only called once function1 has reached an apropriate state.

发布评论

评论列表(0)

  1. 暂无评论