Repeated Synchronous AJAX calls based on response - javascript

I know there are plenty of examples on how to make synchronous AJAX calls (using deferred promises) but my issue is a little different. Here is what I am trying to do
Make an AJAX call
If the response contains a certain value then loop around again and make another AJAX call with different parameters. Value of Parameters will be dependent upon the response from the first AJAX call so have to wait before making the second AJAX call.
If the response contains (exit = true) then exit the loop.
I understand that if the server never returns condition 3 we would be in an endless loop.
How do I continue looping on an AJAX call until a the response from the AJAX call contains a certain value?

Put the code to make the AJAX call in a named function. The callback function of the AJAX checks whether the response contains exit = true. If not, it calls the named function again to make the next AJAX call with the updated function.
function call_ajax(params ...) {
$.ajax({
url: "url",
data: { whatever },
dataType: 'json'
success: function(response) {
if (!response.exit) {
// calculate new parameters
call_ajax(new_params ...);
}
}
})
}

Related

Multiple jquery ajax request - ways to handle it

If there is jquery ajax loading and I fire another ajax by quickly clicking the button, it kind of gets stuck. How can I handle multiple requests fired together?
How do I do following?
Discard/abort all previous requests and only process the latest one.
Do not allow new request until previous request completes (variation: can be same ajax request or any new ajax request from the page).
AJAX is Asynchronous. So you can fire them at the same time.
Or in the success callback (or .done() callback), you can call one request after another. So it will be easy to manage your issue (you click the button but get stucked), because you can control.
$.ajax({
url: "http://..."
})
.done(function( data ) {
// Other AJAX call
// or restore disabled elements
// while you were receiving the response.
});
If you want a work-around, just tell me.
you can use ajax "beforeSend" to lock the current request.So that user can send a new request only if the previous one is done. As for the process sequence, you can use a global value to store data and always assign it with the new response value.
function request(callback){
if(!$btn.hasClass('disabled')){
$.ajax({
type:'...',
url:'...',
beforeSend:function(){
$btn.addClass('disabled');//so that user cannot send a new request
},
success:function(data){
window.g_data = data;
callback && callback()//success callback
$btn.removeClass('disabled');
}
})
}
}
function callback(){
//process window.g_data
}
Have a look at this library:
Async is a utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript.
Async

Pipelining ajax http requests and execute the success function on Latest request only

I am using jquery ajax api to call a web method, and on success i am implementing a functionality like showHideDomElement.
function showHideDomElement(data)
{
if(data == 1 )
$('#selector').show();
else
$('#selector').hide();
}
and this is how i call it
function Validatebatch() {
$.ajax({
type: "POST",
url: getControllerURL("/Invoice") + "/ValidateBatch",
data: {
"Id": $('#someselector').val()
},
async: true, // i tried with 'false' but it affect performance
dataType: "json",
success: function(data) {
showHideDomElement(data);
}
});
}
The ajax request to Validatebatch function raised multiple times, so there are multiple active http request pointing the url completing at different time.
Due to Asynchronous behavior, the success callback can execute at different orders.
The order of finishing up is creating the problem. Please suggest a way that can bound the ajax request to behave/complete in the order it is executed (Please suggest other than jquery async property)
Thanks
First of, you have to rewrite your Validatebatch function so it return the Promise generated by the $.ajax call, e.g.:
function Validatebatch() {
return $.ajax({
then you must store the promise of each Validatebatch call and use it to trigger the next Validatebatch only after the previous has completed, you should have something like:
promise = Validatebatch(); // call Validatebatch the first time and store the returned Promise object
promise = promise.then(Validatebatch); // another call to Validatebatch, only triggered after the previous has ended
promise = promise.then(Validatebatch); // again, this third Validatebatch call will only happen after the second one has ended.

jQuery $.ajax success firing last [duplicate]

This question already has answers here:
Easy to understand definition of "asynchronous event"? [closed]
(11 answers)
Closed 7 years ago.
I have the following Javascript and it's returning results out of the order I would expect them.
function getCurrentItems(id){
alert("2");
$.ajax({
url: "somePHPurlthatspitsoutajsonencodedArray.php",
type: "POST",
dataType: "json'",
data: {id:id},
success: function(data){
alert("3");
}
});
alert("4");
}
$(document).on('click', '.eventClass', function(e){
alert("1");
var id = "someID";
var results = getCurrentItems(id);
alert("5");
});
I would think I'd get alerts in the order of 1, 2, 3, 4, 5.
Instead I get them in the order of 1, 2, 4, 5, 3.
I just can't figure out why that success alert (5) fires last?
AJAX is short for asynchronous JavaScript and XML. Asynchronous is the keyword here. I'll use an allegory to explain async.
Lets say you're washing dishes manually. You can't do anything else while doing that, so it is synchronous.
Lets say you put your dishes in a dishwasher. You can do other things, you've delegated the task to the dishwasher, so this is asynchronous. Asynchronous is generally better, because you can do multiple things at one time. Javascript only asyncs when requesting info from the server, as Javascript is single threaded (it only runs on 1 CPU core and can only do one thing at a time on it's own).
A callback is a function that is called when the async task completes. The dishwasher finishes, so now you have to empty it as soon as you complete what you're doing when it finshed.
So in your code, you start the dishwasher, say you're going to alert("3") when the dishwasher finishes running, and then you go alert 4 and 5. Then when the dishwasher finishes/your server returns data, you alert 3 like you said you would.
That make sense?
The reason that you give a success callback function in an ajax request is that the request might take some time to return, but your code can continue running. In this case the ajax request is sent, and the success function is remembered for later, then your code continues (alerting 4 and 5). When the browser receives the response to the ajax request it calls the success function (alerting 3).
The way that Javascript works, only one thread is run per browser tab, so event handlers are not called until any previously running code is completed. Therefore, even if your getCurrentItems function were to take several seconds to complete, by which time the server response had returned, the success function would still not be called until after your function had completed.
Edit: Because an ajax call can take some time, it is not generally desirable to be able to call a function like getCurrentItems which includes an ajax request, and wait for the response. If you do this, then you are likely to leave your browser window unresponsive, and you will have to deal with potential errors from the ajax call. Instead, you should put any code that you wish to run which relies on the ajax result in the success function, or in another function which you call from there. As languages go, Javascript is very good for doing this kind of thing. You could even take a callback function as an argument to getCurrentItems, and run it from the success function.
As others have mentioned, you're getting the results in the order you see because the ajax request doesn't return with it's data and call your success callback until the response is received, but code continues to execute immediately after the $.ajax call.
To get the workflow you're probably expecting, you could use promises, or simply pass in a callback:
function getCurrentItems(id, onSuccess){
alert("2");
$.ajax({
url: "somePHPurlthatspitsoutajsonencodedArray.php",
type: "POST",
dataType: "json'",
data: {id:id},
success: function(data){
alert("3");
onSuccess(data);
}
});
alert("4");
}
$(document).on('click', '.eventClass', function(e){
alert("1");
var id = "someID";
var results = getCurrentItems(id, function(data){
console.log('data',data);
alert("5");
});
});

Queue multiple AJAX requests, waiting for response and not freezing browser? [duplicate]

This question already has answers here:
Sequencing ajax requests
(10 answers)
Closed 9 years ago.
I am working a script, I need to loop an array of AJAX requests:
$('#fetchPosts').click(function(){
for(var i=0; i < link_array.length; i++) {
settings = {
// some object not relevant
}
var status = main_ajaxCall(settings, i); // ajax call
}
});
function main_ajaxCall(settings, i) {
$.ajax({
type: "POST",
url: "../model/insert.php",
data:{obj_settings: settings},
dataType: "json",
cache: false,
success: function (data) {
// some handeling here
return 0;
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
return 1;
},
};
Why does the AJAX requests fire instantly? It does not seem to wait for a response from model/insert.php, is there any way to force it to wait for a response before firing the next AJAX request?
EDIT 1:
It seems I wasnt clear, sorry, I dont want it to wait, I want to queue up the calls.
I cant make the call in one request, this is impossible in my current situation.
Set async to false if you want to wait for a response (default: true)
$.ajax({
async: false,
...
http://api.jquery.com/jQuery.ajax/
If you do not want blocking, you can set a success handler function using .ajaxComplete(), and you have to keep track of active AJAX connections if you want to wait for all to complete - How to know when all ajax calls are complete
The best solution would be to minimize the number of AJAX requests to one. If you have to make a loop of AJAX requests, the logic could be simplified somewhere (put that in the server perhaps?)
EDIT 1: (In response to OP edit)
If you want to queue the AJAX requests, this question has been answered before here:
Sequencing ajax requests
Queue ajax requests using jQuery.queue()
You could also use these libraries (all you needed to do was Google):
https://code.google.com/p/jquery-ajaxq/
http://codecanyon.net/item/ajax-queue-jquery/full_screen_preview/4903957
http://schneimi.wordpress.com/2008/03/10/multiple-ajax-requests-problems-and-ajaxqueue-as-solution/
It fires instantly and doesn't wait around because that's what AJAX does best (The first A stands for asynchronous).
The request to a server could take a long time to respond, and in most cases, don't want user's browser's freezing up or stopping them from doing anything else. If you do, you could probably just use a normal request.
This is the reason you give it functions for success error, so it can call them when the server responds.
If you want nothing to be able to happen in the browser while you're calling insert.php, you could drop an overlay (eg. dark div) over everything with a loading image and remove it on success.
Maybe replace the $('#fetchPosts') element with "loading..." text and then reverse it when done. Hiding visibility of the fetchPosts element and adding a different "loading.." element is a nice way.
Your AJAX call will wait for a response from the server, but wil do so asynchronously. That is, your script will continue to execute rather than block the browser while the server responds. When the server responds (or when the request times out - usually several seconds) your success: or error: functions will then execute.
The effect of your code here is to create several concurrent requests based on the link_array length.
You could specify async:false in your AJAX call, but this would freeze the browser while all the AJAX calls are made.
You should rewrite your code to execute all the handling as part of your success: function. I'd recommend you rewrite your code to assemble all your request into one, and make one AJAX call rather than several, and have the server return all the responses as one block. I can't suggest exactly how you do that - it's implementation dependent.
EDITED:
In response to your clarification, if you want them to be called in order, you'll need the success function to call the next one. You'll then have a chain of success calls the next, whose success calls the next, whose success calls the next.. etc until the last one which does the final processing. One way would be to pass the call number to the success function.

Recursive Ajax Upon Success

I'm trying to make an ajax request recursively upon each success response that is returned from each request Would I be prone to stack overflows? If so do you have any better way of doing this? My requirements is to initially perform an ajax request and if the json returned is not done perform another ajax request with the same parameters... etc until i get a done flag.
go: function (r) {
Ext.Ajax.request({
url: 'bleh',
success: function (response) {
var data = Ext.decode(response.responseText); // decode json into object
r.update();
if (!data.isDone) go(r);
}
});
}
This is not actually recursion so there is no danger of stack overflow. It may look like recursion, but because the ajax call is asycnchronous, your go() function only starts the ajax call and then the go() function finishes right away while the ajax call is underway. Thus, the success handler is called long after the go() function has already finished. so, it's not actually recursion and there is no stack buildup.
It may look like recursion from the visual effects of the code, but because the ajax call is asynchronous and the success handler is called long after the go() function has returned, there is no stack buildup.

Categories

Resources