1
function jQueryFunction(url,callback)
{ 
    $.ajax
    ({
        type: "GET",
        async: false,
        url: url,
        dataType: "jsonp",
        jsonp: "callback",
        jsonpCallback: "tpsHandler",
        success: function(json)
        {
            return callback(json);
        }
    });  
}

function tmpFunction(callback) 
{
    var jsonArray = new Array();
    var i = 0;

    while(true)
    {
        for(var j = 0; j < url_array.length; j++)
        {
            jQueryFunction(url_array[j], function(json){
                jsonArray[j] = json;
                i++;
            });
        }

        if(i >= url_array.length)
        {
            return callback(jsonArray);
        }
        else
        {
            alert(i);
        }
    }
}

When I call tmpFunction the website keeps displaying "0" to me. Why is i always 0? Does tmpFunction never run the for loop?

5
  • 1
    Its asynchronous. A similar question that I responded to awhile back: stackoverflow.com/questions/14989827/… Commented Oct 3, 2013 at 22:48
  • 1
    You can not do while(true)! It is going start crashing Commented Oct 3, 2013 at 22:49
  • What are you trying to achieve here?? Commented Oct 3, 2013 at 23:02
  • you should be using "deferreds" and $.when to look for execution of the final AJAX call... Commented Oct 3, 2013 at 23:04
  • Why do you want to create so many calls to the server at the same url through this recursive technique? Commented Oct 3, 2013 at 23:09

3 Answers 3

1

From the jQuery documentation:

By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active. As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done() or the deprecated jqXHR.success().

As shown above, you can't use jsonp with synchronous requests. So yes, your success callback is not getting executed (not even sure whether jQuery would trigger a callback if a function is synchronous in lieu of just return the value).

Furthermore, I suggest that you never make synchronous AJAX requests since network requests are long-running operations that can destroy user experience. Instead, take @Altinak 's advice and use Deferred objects.

Sign up to request clarification or add additional context in comments.

2 Comments

And on a higher (yet slightly less related) level, be very careful of how you use this function. Whomever maintains the API servers that your constant network requests are thrashing is probably not going to be a happy camper :)
I believe you meant "never make synchronous AJAX requests"
0

A better solution to this entire problem is to use deferred objects.

I'm going to ignore the while (true) bit for now, since that doesn't make sense:

function jQueryFunction(url)
{ 
    return $.ajax({
        type: "GET",
        async: true,                  // NB: **not** false
        url: url,
        dataType: "jsonp",
        jsonp: "callback",
        jsonpCallback: "tpsHandler"   // any good reason why you're defining this?
    });  
}

function tmpFunction(callback) 
{
    var def = [];     

    for (var i = 0; i < url_array.length; ++i) {
        def.push(jQueryFunction(url_array[i]));
    }

    return $.when.apply($, def).done(callback);
}

This will run all of the AJAX queries in parallel (subject to per-host client connection limits) and once they're all done, callback will be invoked with each of the results (in submission order) in the arguments array.

NB: this isn't quite the same as your original semantics which has callback passed a single parameter that is the array of results. If you want to keep that, use:

.done(function() {
    var args = [].slice.call(arguments, 0);
    callback.call(this, args);
});

Comments

0

Place the i after the jQueryFunction call.

Don't forget to place a "break;" after alert(i) to get out of the while loop.

If the i must be inside the callback in jQueryFunction call use a done to place your code to execute after ajax, and don't use i. Change async to true in the ajax call to get done to work.

$.ajax( //your settings
).done(function(data){
    //check the value in data instead of i.
    //due to .ajax being asynchronous code that needs to wait needs
    //to be in .done or the success callback.
});

2 Comments

the OP is using async: false - .done won't work unless he changes to true (which he should do, of course).
@Alnitak Whoops missed that. Changed the answer to reflect that.

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.