0

Here is a magic code:

function() {
        var result='';
        for (var key in TRAINER_STEPS){
            if (TRAINER_STEPS.hasOwnProperty(key)) {
                $.get('steps/trainer.step.'+key+'.html')
                    .done(function(data) {
                        console.log(data); // HERE DATA IS VALID HTML DATA
                        result += '<div '+(key == TRAINER_DEFAULT_STEP ? 'class="hiddenStep"' : 'class="currentStep"')+' data-step="'+key+'">'+data+'</div>\n'; // AND HERE NOTHING HAPPEND
                    })
                    .fail(function(jqxhr, settings, exception) {
                        console.log("[el5s] Load step steps/trainer.step."+key+".html failed. Error: "+exception);
                });

            }

        }
        console.log(result); // EMPTY HERE
        return result;
    }

$.get works good, and data is received properly, but my function returns totaly empty result. See my coments. What's wrong with it?

ovnia
  • 2,412
  • 4
  • 33
  • 54
  • 2
    Welcome to the wonderful world of **async**! You can't do that. – SLaks Oct 22 '13 at 21:35
  • 1
    You also have the infamous block scope issue. – SLaks Oct 22 '13 at 21:35
  • 1
    Your `.get` calls are executed asynchronously. Your `console.log()` and `return` statements are executed **before** the data is returned. –  Oct 22 '13 at 21:37
  • 1
    *"`AND HERE NOTHING HAPPEND`"* is false, it definitely updated the result variable. you just didn't wait long enough to access it's contents. – Kevin B Oct 22 '13 at 21:38
  • @SLaks, for my own education, what is the block scope issue? – Katie Kilian Oct 22 '13 at 22:06
  • @CharlieKilian: http://stackoverflow.com/q/750486/34397 http://stackoverflow.com/q/3572480/34397 – SLaks Oct 22 '13 at 22:15

1 Answers1

0

The design of your program needs to be re-thought. In general, what you need to do is split the function into three different functions: The part that happens before the AJAX call, the part that happens if the AJAX call is successful, and the the part that happens if the AJAX call is not successful.

Instead of this pseudocode process:

function doSomething() {
    // code to do whatever
    var data = getDataFromWebService();
    // code to work with the data
}

use this one:

function doSomething() {
    // code to do whatever

    $.get('steps/trainer.step.'+key+'.html')
        .done(onSuccess)
        .fail(onFailure);
}    

function onSuccess() {
    // code to work with the data
}

function onFailure() {
    // code to respond to a web service that is down whatever
}
Katie Kilian
  • 6,815
  • 5
  • 41
  • 64
  • it's not good, coz i need to load several files and create divs with it's datas – ovnia Oct 22 '13 at 22:22
  • You still can. You just have to split the single function you are thinking of into two functions: The part that happens up to and including the AJAX call that loads the data, and the part that happens after the data is returned from the server. (And a third function, which is called if the data can't be loaded.) – Katie Kilian Oct 22 '13 at 22:24
  • So whereever you were going to create divs with the data? Put that into its own function. And where you were going to retrieve the data? End the function after making the AJAX call, and put everything after it goes into the new function, that is executed by jQuery after the data is successfully loaded. – Katie Kilian Oct 22 '13 at 22:25
  • is there a way to make it nonAsync? – ovnia Oct 22 '13 at 22:26
  • Sure. You can do what @Anass suggested in the answer below. But I don't recommend that route. It's going to be frustrating to users and harder to support in the long run. – Katie Kilian Oct 23 '13 at 13:18