0

I am trying to update a global variable within a callback function (see code below)

function FunctionOne() {
    var result = "";

    for (var i = 0; i < 10; i++) {
         AjaxFunction(function (data) {
            result += data;
         });
    }

    alert(result);
}

function AjaxFunction(callback) {
    $.ajax({
        url: '/test',
        type: 'GET',
        success: function(data) {
            callback(data);
        }
    });
}

When I alert result it always seems to be blank. Can you guys please tell me whats wrong?

COBOL
  • 1,031
  • 8
  • 16
  • 32

2 Answers2

3

Result is not global, it is only defined within the scope of FunctionOne(). However in your example you are alerting the value, before it has been assigned as the Ajax call appears to run asynchronously. Instead try alerting after you update your value.

function FunctionOne() {
var result = "";

for (var i = 0; i < 10; i++) {
     AjaxFunction(function (data) {
        result += data;
        alert(result); // this should have the value
     }
}

alert(result); // this should be empty
}
Ian
  • 33,605
  • 26
  • 118
  • 198
1

There are two parts to your question that need to be resolved - the first relates to the asynchronous nature of AJAX and how results are returned - for that see the canonical answer to the question that this was originally marked as a duplicate of.

The second part is how to make the final answer depend on the asynchronous completion of all ten AJAX requests:

function functionOne() {
    // initiate ten requests, storing the promises in an array
    var def = [];
    for (var i = 0; i < 10; ++i) {
        def[i] = AjaxFunction();
    }

    // wait for all the promises to complete, with the
    // eventual result also being returned as a promise
    return $.when.apply($, def).then(function() {
        // take a copy of the arguments
        var args = [].slice.call(arguments, 0);   

        // concatenate them all together
        return args.reduce(function(prev, current) {
            return prev + current[0];   // each arg is actually a 3-element array
        }, "");
    });
}

function AjaxFunction() {
    return $.get('/test');  // NB: using promises - no callback required
};

// NB: functionOne() is now also async - you have to wait
//     for the promise to be resolved before using the result

functionOne().then(function(result) {
    alert(result);
)};

See http://jsfiddle.net/alnitak/5s28G/ for a working demo.

Community
  • 1
  • 1
Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • which version of jQuery includes Promises? – COBOL Jun 02 '14 at 13:33
  • @COBOL Anything from 1.5 onwards. The usage of `.then()` above is from 1.8 onwards (ISTR) – Alnitak Jun 02 '14 at 13:35
  • The project I'm working on is a legacy project and is using 1.4, so I will have to solve this problem without promises – COBOL Jun 02 '14 at 13:43
  • @COBOL that's a shame - they really are the best way to solve this. FWIW, there are third party Promises libraries that you could potentially add to jQuery 1.4 that would give very similar functionality (`Q`, perhaps - https://github.com/kriskowal/q ?) – Alnitak Jun 02 '14 at 13:44