0

I have three each loops and all three may or may not be dependent on each other depending upon page level filters selected .There are total 3 filters

if(filter1 is selected) {
  //runs first $.each loop and alters some of custom attr to DOM element  
}

if(filter2 is selected) {
  // Checks if filter1 was selected and are there any attr changes done by it   
  // runs second $.each loop and alters some of custom attr to DOM element   
}

filter3 .... So on

Problem is I need to know if first loop in filter1 has completed its task , then only run second filter loop so that I may get all attr changes done by filter1 perfectly.So I am trying to user Deferred object .Below is my code.

var defer = $.Deferred();
if(filter1) {
  $.each()
    .promise
    .done(function(){
      defer.resolve();
      return defer.promise()
    });
}

// same goes for filter2 and filter3

Now I want if filter1 is selected [execute loop and return promise] or not selected [return promise] and then go into second filter following same process.How can I achieve it , also how would I know that all 3 loops have completed its execution . Note : There are no ajax call in above process at all.

3
  • 1
    The nature of the "filter1" operations is ambiguous. Overall, the question implies asynchronous, but the description "alters some of custom attr to DOM element " implies synchronous. Commented Apr 18, 2015 at 8:46
  • @Roamer Yes you are right Commented Apr 18, 2015 at 10:00
  • Then let's assume they are asynchronous. Commented Apr 18, 2015 at 11:33

3 Answers 3

2

Use $.when for aggregation and then chaining.

function handleFirstFilter(){
    if(firstFilterSelected){
        var ps = [];
        $.each(elements, function(el){
            ps.push(el.animate(...).promise()); // add all the promises
        });
        return $.when.apply($, ps); // aggregate over them
    }
    return $.Deferred().resolve(); // return an empty promise resolved, nothing to do
}
// the other two filters are similar in pattern, can extract it to a function

// now execute them all with each stage waiting for the previous.
handleFirstFilter().then(handleSecondFilter).then(handleThirdFilter)
Sign up to request clarification or add additional context in comments.

1 Comment

How would I know that all then statements have completed execution
2

If your stages depend only on completion of (not data from) the previous stage, and the three filter-handlers differ only in :

  • a particular boolean state,
  • the elements acted on,
  • the asycn function to be applied to each element,

then you could write a generalized handleFilter() function as simple as :

function handleFilter(selected, asyncFn) {
    // return an aggregated promise or null.
    return selected ? $.when.apply(null, $.map(this, asyncFn)) : null;
}

As written, handleFilter() must be called with .bind(), .apply() or .call() in order to establish the value of this.

You would then use handleFilter.bind() to make three executables, one for each filter, and pass them to a chain of .then()s for serial execution.

$.when()
    .then(handleFilter.bind(elements_1, firstFilterSelected, asyncFn_1))
    .then(handleFilter.bind(elements_2, secondFilterSelected, asyncFn_2))
    .then(handleFilter.bind(elements_3, thirdFilterSelected, asyncFn_3))
    .then(function() {
        //everything complete
    });

Each stage will wait for the previous one to complete.

2 Comments

Thanks I used your Idea but modifed a bit say callfunction1().then(function(){callfunction2().then(function(){callfunction3().then(function(){console.log("I am Done")})})}); But in above code how would I handle , say if callfunction2() is failed or in other words how can know that a particular function is failed
"... a bit ... "! Has any of my idea survived? I omitted failure handling as it wasn't in the question. How you handle errors depends on the desired behaviour. There are two basic options - stop-on-failure or continue-on-failure.
0

"alters some of custom attr to DOM element"

is not an asynchronous action (like a timeout, ajax request, or user interaction). It will have been executed, and finished executing, when the loop is over. All the new attribute values can be observed from the second loop.

You do not need promises here, just put your synchronous statements in the right order and they will be evaluated sequentially.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.