2

I have read other answers here and couldn't exactly match my issue. Should be simple for someone with lots of experience in Promises. Code below, I need help fixing up the Recursive function because everything that happens in that ajax call is not available in first done. Code below will explain (Note the TypeScript syntax):

//Main
private Start(){
    this.PopulateSomething().done(() => {
        alert('done');
    });
}

private PopulateSomething(): JQueryPromise<any> {
    var dfd: JQueryDeferred<any> = jQuery.Deferred<any>();

        //app.ExecuteAjax is just a wrapper for a ajax call.. note i'm using callbacks
        app.ExecuteAjax("SomeParamater1", function (returnedObject) {
            //Do something with returnedObject                    
            $.each(returnedObject.something, function () {
                app.RecursivelyDoSomething(this);                                                        
            });                              
            dfd.resolve();
        });
    return dfd.promise();
}

private RecursivelyDoSomething(Thing: any) {     
    //Do something with Thing           

    //Anything that happens within this Ajax call is not available when alert('done'); is executed
    app.ExecuteAjax("SomeParamater1", function (returnedObject) {
        $.each(returnedObject.something, function () {
            app.RecursivelyDoSomething(this);                                                        
        });
    });
}
Fox
  • 891
  • 3
  • 9
  • 30
  • 1
    You will need to make `RecursivelyDoSomething` return a promise. Instead of `$.each` use `$.map` so that you get an array of promises, which you then can [wait for](http://stackoverflow.com/q/5627284/1048572). Oh, and don't use the [deferred antipattern](http://stackoverflow.com/q/23803743/1048572) – Bergi May 07 '15 at 04:06
  • @Bergi I like the idea and approach. Still struggling to visualise it though. I understand returning a promise on RecursivelyDoSomething function but when do I actually call the resolve? Sorry, I know only 2 things about promises: promise, and resolve :-) – Fox May 07 '15 at 08:02
  • 1
    A promise that is returned from a function is resolved with that function's eventual result, when everything that the function does is done. So it would resolve when the ajax call and all recursive calls are done. – Bergi May 07 '15 at 13:24
  • 1
    Q1: Are you populating a tree or something using the result of each Ajax call to provide more nodes? Q2: Do you want the operations to run sequentially, in parallel (restricted by the browser throttling), or some combination of the two? Q3: Is the data fixed-depth, or does this really need to be recursive? – iCollect.it Ltd May 11 '15 at 11:20
  • Hey @TrueBlueAussie. Thanks for your interest in helpgin solve this. Q1: Yes, I am populating a tree (Using Knockout recursive Template). Q2. I can do syncronous but don't want the browser to lock up. Q3. Unfortunately, it's not fixed depth data, so has to be true recursion... – Fox May 13 '15 at 03:42

1 Answers1

-1

Seems you want to recursively make ajax queries and only want to execute done after the last one. One way to do that would be to keep a count of pending ajax queries, increment this count based on Thing and decrement this count from based on Ajax finishing. And then only resolve dfd once count = 0.

basarat
  • 261,912
  • 58
  • 460
  • 511
  • 1
    No, please not. Use promises when you have them at hand! No need for manually counting anything. – Bergi May 07 '15 at 04:08