I am writing a function to use ajax to get the instructions from a back end server while the page is loading. My ajax code fetches the instructions based on the number and prints the instructions using the variable response.setText in this <p id="loadText"></p> element using jquery and the console. Here is my ajax function:
function ajaxFetch(s) {
var success = false;
$.ajax({
type: "POST",
url: "post.php",
data: {
step: s
},
async: false,
dataType: 'JSON',
success: function (response) {
$("#loadText").text(response.stepText);
console.log(response.stepText);
success = true;
}
});
return success;
}
I am trying to use another function to loop through steps no matter how many there are, but here are my problems that I keep running into:
ajaxFetch() is not updating the DOM until last execution
tried setTimeout() and not updating DOM
for loop looping through ajaxFetch() too quickly
response.stepText prints in the console on time, but does not update DOM on time
Here is a sample loop I have tried:
function uploadSteps(maxStep) {
for (var x = 1; x <= maxStep; x++){
setTimeout(ajaxFetch(x), 20);
}
}
Sorry this is so long and thanks in advance.
By the time your for-loop completes, say 20 iterations, your ajax call in ajaxFetch only would have received the response for the first few calls and what you see in the end is the response for the last ajax call. You can use this link to understand how async calls work in javascript
https://rowanmanning.com/posts/javascript-for-beginners-async/
So the answer is, you need to wait till the first ajax call completes and then call the method again with a timeout of 20ms, like this
var globalMaxSteps = 1;
var startIndex = 1;
function ajaxFetch(s) {
$.ajax({
type: "POST",
url: "post.php",
data: {
step: s
},
async: false,
dataType: 'JSON',
success: function (response) {
$("#loadText").text(response.stepText);
console.log(response.stepText);
startIndex++;
if(startIndex <= globalMaxSteps) {
setTimeout(function(){
ajaxFetch((startIndex);
},20);
} else {
console.log("All Iterations complete");
}
}
});
}
function uploadSteps(maxStep) {
startIndex = 1;
globalMaxSteps = maxStep;
setTimeout(function(){
ajaxFetch(startIndex);
},20);
}
First, we need to fix mistakes in the uploadSteps function:
function uploadSteps(maxStep) {
// here change `var x` to `let x` to avoid problems
// like here - https://stackoverflow.com/q/750486/5811984
for (let x = 1; x <= maxStep; x++){
setTimeout(function() {
// notice how here ajaxFetch(x) is wrapped into a function,
// otherwise it gets called right away
ajaxFetch(x)
}, 20);
}
}
Now here's another problem - all the setTimeout will be called with 20ms delay, that means that all of them will be executed at the same time, but ~20ms after uploadSteps() was called.
Let's see what happens when maxStep=3 (assuming your CPU is very fast because that is irrelevant for understanding the problem):
Time passed | what happens
--------------------------
0ms | setTimeout(ajaxFetch(1), 20) is called
0ms | setTimeout(ajaxFetch(2), 20) is called
0ms | setTimeout(ajaxFetch(3), 20) is called
20ms | ajaxFetch(1) is called
20ms | ajaxFetch(2) is called
20ms | ajaxFetch(3) is called
So as you see all ajaxFetch's are called at the same time, and I am assuming that's not exactly what you need. What you might be looking for is this:
Time passed | what happens
--------------------------
0ms | setTimeout(ajaxFetch(1), 20) is called
0ms | setTimeout(ajaxFetch(2), 40) is called
0ms | setTimeout(ajaxFetch(3), 60) is called
20ms | ajaxFetch(1) is called
40ms | ajaxFetch(2) is called
60ms | ajaxFetch(3) is called
Which can be implemented with a slight change to your code
function uploadSteps(maxStep) {
for (let x = 1; x <= maxStep; x++){
setTimeout(function() {
ajaxFetch(x)
}, 20 * x); // change delay from 20 -> 20 * x
}
}
Also it looks like you don't need to return anything from ajaxFetch(), so it's better to make it async so it does not block the code execution:
function ajaxFetch(s) {
$.ajax({
type: "POST",
url: "post.php",
data: {
step: s
},
// async: false, -- remove this, it's true by default
dataType: 'JSON',
success: function (response) {
$("#loadText").text(response.stepText);
console.log(response.stepText);
}
});
}
Even if you actually do need to return something for fetchAjax(), it's better to keep it async and use callbacks/promises. jQuery actually strongly discourages using async: false in any case.
If the reason you added setTimeouts is to make sure all the steps are executed in order, then it's not the right way to do that. The problems are:
Let's say it took 100ms for the server to respond to the first request, and 10ms for the second one. Even with the 20ms delay the second request will be executed first. And just increasing the delay is not the solution, because:
If your server responds much faster the delay, you are introducing an unnecessary wait for the user.
It's better to add a callback from ajaxFetch() that will be called when ajax fetching is done, and then you'd call the next ajaxFetch() after you receive the callback.
Related
I have two functions periodically called via setInterval. The goal is to defer Function B until Function A is done (and vis versa). Currently, Function A will start, complete some of its subroutines, but not reach the end before Function B begins.
I've tried passing Function B as an argument of Function A. I am not sure if that was sufficient to create a callback. I also tried jQuery's $.when(setInterval(functionA, 10000)).then(setInterval(functionB, 5000)).
How do I ask JavaScript to wait for functions/blocks of code to finish? Thank you in advance.
Edit: Below is code very similar to my original. Sorry for not being concise.
Function A, getFruits(): There is a remote JSON that changes on its own (fruits.json). getFruits() does two things: 1) It empties an array, [allFruits] (just in case); 2) It adds all the names of fruit currently in the remote JSON to [allFruits]. Now, [allFruits] is an instanced copy of the remote JSON. Before this question, I only called getFruits() once, at startup; in other words, I did not use setInterval for getFruits().
Function B, checkFruits(): Now checkFruits() periodically (setInterval(checkFruits, 5000)) compares [allFruits] to the remote version. If any fruit was added to the remote version, checkFruits appends [allFruits] with those fruits' names; it also runs useful code (i.e. pushes the new names to an array [queue]).
For this implementation, it is important to create an initial list so only new (post-startup) fruit trigger the useful code of checkFruits(). Moreover, it is important only to add (never subtract) names from [allFruits] within a session. This is to prevent a new fruit from triggering the useful code more than once per session.
Problem: Now I want to make getFruits() (Function A) periodic. Because getFruits() empties [allFruits], it will allow the names that built up to again trigger useful code (but only once in between invocations of getFruits()). However, when I use setInterval(getFruits, 10000), there are times (in this example, always) when getFruits() overlaps with checkFruits(). When that happens, I notice only part of getFruits() finishes before checkFruits() starts. The console.log() messages appear in this order: 'getFruits() start:', 'checkFruits():', 'getFruits() end:'. Furthermore, my useful code is ran before getFruits() finishes (this is what is really undesired), and [allFruits] gets duplicates. This would not occur if getFruits() completely finished before checkFruits() jumped in.
debugging = true;
var debug = function() {
if (debugging){
console.log.apply(console, arguments)
};
}
var allFruits = [];
var queue = [];
var getFruits = function() {
allFruits = []; // Empty the list
debug('getFruits() start:', 'allFruits =', allFruits, 'queue =', queue);
$.ajax({
url: 'fruits.json',
dataType: 'json',
success: function(data) {
data.fruits.forEach(function(element) {
allFruits.push(element.name);
});
debug('getFruits() end:', 'data =', data, 'allFruits =', allFruits, 'queue =', queue);
},
});
}
var checkFruits = function() {
$.ajax({
url: 'fruits.json',
dataType: 'json',
success: function(data) {
data.fruits.forEach(function(element) {
if (allFruits.indexOf(element.name) === -1) {
queue.push(['fruit', element.name]);
allFruits.push(element.name);
}
});
debug('checkFruits():', 'data =', data, 'allFruits =', allFruits, 'queue =', queue);
}
});
}
getFruits();
setInterval(checkFruits, 5000);
// setInterval(getFruits, 10000); // When I try this, checkFruits() does not wait for getFruits() to finish.
The analogy of my actual remote resource is fruits.json. fruits.json can simply be the following:
{"fruits":[{"name":"apple","color":"red"},{"name":"banana","color":"yellow"},{"name":"tangerine","color":"orange"}]}
Again, the actual, remote JSON changes independently.
What you have here are two methods that each do asynchronouse stuff. Here are some good stack overflow posts on what that means.
Easy to understand definition of "asynchronous event"?
Does async programming mean multi-threading?
Are JavaScript functions asynchronous?
We have no idea how long it will take for an asynchronous call to finish. In your case, the AJAX request could take up to a few seconds depending on network speeds so regardless of when each of these methods are executed you CANNOT know which one will finish first. So what to do? Well, generally when you write/use an asynchronous method (like $.ajax) you give it a callback that will be executed when the asynchronous work is finished. And you have done this in the form of the success callback. And here is the good news. The success callbacks are SYNCHRONOUS (note the missing a). This means that the "useful code" in the success callback that needs to be run when a request finishes will complete (so long as none of it is async) before the "other useful code" in the other success callback is executed at all. And this works no matter which request finishes first. Each success callback will always wait for the other. So I think what was confusing you was your debug statements. If you add the following statements to your code the execution flow may make more sense:
debugging = true;
var debug = function() {
if (debugging) {
console.log.apply(console, arguments)
};
}
var allFruits = [];
var queue = [];
var getFruits = function() {
debug("getFruits: make request");
$.ajax({
url: 'fruits.json',
dataType: 'json',
success: function(data) {
debug("getFruits: start processing");
allFruits = []; // Empty the list
data.fruits.forEach(function(element) {
allFruits.push(element.name);
});
debug('getFruits: finished processing');
},
});
debug("getFruits: request sent, now we wait for a response.");
}
var checkFruits = function() {
debug("checkFruits: make request");
$.ajax({
url: 'fruits.json',
dataType: 'json',
success: function(data) {
debug("checkFruits: start processing");
data.fruits.forEach(function(element) {
if (allFruits.indexOf(element.name) === -1) {
queue.push(['fruit', element.name]);
allFruits.push(element.name);
}
});
debug("checkFruits: finished processing");
}
});
debug("checkFruits: request sent, now we wait for a response.");
}
getFruits();
setInterval(checkFruits, 5000);
// setInterval(getFruits, 10000); // When I try this, checkFruits() does not wait for getFruits() to finish.
After thinking about it I believe the only reason things may not have been behaving as expected is because you're emptying the allFruits array outside of the callback. If you move it as I have done I would think everything should work fine.
Now, I don't know why you need to re-initialize the data since each time you make the request your getting the latest information but lets roll with it. Since both methods make the same request lets consolidate that into a single method. No need to duplicate code ;). And since all of your examples have the getFruits running twice as slow as the checkFruits we could easily add a counter to accomplish the same sequence of events like so:
debugging = true;
var debug = function() {
if (debugging) {
console.log.apply(console, arguments)
};
}
var allFruits = [];
var queue = [];
var count = 0;
var doOneThing = function(data) {
//do stuff
}
var doAnotherThing= function(data) {
//do other stuff
}
var requestFruits = function() {
$.ajax({
url: 'fruits.json',
dataType: 'json',
success: function(data) {
// if count is even...or, do this every other time.
if (count % 2 === 0) {
count++;
doOneThing(data);
}
// do this everytime
doAnotherThing(data);
},
});
}
setInterval(requestFruits, 5000);
Hope this helps. Cheers.
your last code example first executes setInterval(functionA), and when the deferred execution of functionA is setup, executes setInterval(functionB), meaning that B will called +- 5 seconds after that line is executed, while functionA is called +- 10 seconds.
edit to reflect your additional information:
setInterval(function(){
functionA();
functionB();
}, 10000)
setTimeout(function(){
setInterval(functionB, 10000)
}, 5000)
This is a crude answer. I sense that callbacks can achieve this, but I am not sure how to code them, especially involving setInterval.
I create two global variables, getFruitsIsBusy = false and checkFruitsIsBusy = false. I create an IF for both getFruits() and checkFruits(). Here is getFruits():
var getFruits = function() {
if (checkFruitsIsBusy) { // New
setTimeout(getFruits, 100); // New
return; // New
} else { // New
getFruitsIsBusy = true // New
allFruits = []; // Empty the list
debug('getFruits() start:', 'allFruits =', allFruits, 'queue =', queue);
$.ajax({
url: 'fruits.json',
dataType: 'json',
success: function(data) {
data.fruits.forEach(function(element) {
allFruits.push(element.name);
});
getFruitsIsBusy = false // New; in the success function
debug('getFruits() end:', 'data =', data, 'allFruits =', allFruits, 'queue =', queue)
},
});
}
}
If also using this paradigm for checkFruits(), it seems both functions will wait for each other to finish.
Based on an analysis of the timing of two functions (A and B), consider the following solution (Chionglo, 2016):
Keep state information for each of function A and function B. The state of each function should be set within each of the respective functions.
Create a wrapper function for each of function A and function B. The wrapper function calls on the respective function, and then checks for the state of the respective function.
a. The check in wrapper function A: if function A has reached is final state, clear the interval associated with wrapper function A and schedule an interval for wrapper function B.
b. The check in wrapper function B: if function B has reached its final state, clear the interval associated with wrapper function B.
To begin the process, schedule an interval for wrapper function A.
Sample code:
var ac = Math.round(4*Math.random())+4;
var bc = Math.round(6*Math.random())+6;
var ai;
var Astate = false;
var Bstate = false;
function A() {
// Do your thing for A here.
// The following changes the “state of A” and then determines if the final state has been reached.
ac -= 1;
if (ac<1) Astate = true;
else Astate = false;
}
function B() {
// Do your thing for B here.
// The following changes the “state of B” and then determines if the final state has been reached.
bc -= 1;
if (bc<1) Bstate = true;
else Bstate = false;
}
ai = setInterval("processA()", 1000);
function processA() {
A();
if (Astate) {
clearInterval(ai);
ai = setInterval("processB()", 500);
}
}
function processB() {
B();
if (Bstate) {
clearInterval(ai);
ai = undefined;
}
}
Reference
Chionglo, J. F. (2016). An analysis for timing a set of functions. Available at http://www.aespen.ca/AEnswers/1458200332.pdf.
I'm using jQuery to send an AJAX request, retrieving data from a server.
That data is then appended to an element. This should happen 5 times, but it will always happen randomly either 3, 4, or 5 times. Basically, sometimes the loop will skip the AJAX request, but the majority of the time it catches it. How do I make sure it completes the request five times every time? and what is the reason behind this random behavior of skipping AJAX request?(side note. I've checked the request errors, but it never alerted of a request failure)
Here's my JS:
while (counter < 6) {
$.ajax({
url:'http://whisperingforest.org/js/getQuote.php',
async: false,
dataType: 'jsonp',
success:function(data){
$('.quoteList').append('<li>' + data +'</li>');
totalQuotes++;
}
});
counter++;
}
P.s. this happens on a button press.
Don't do it synchronously. Use the callback. Here is a demo for you: http://jsfiddle.net/y45Lfupw/4/
<ul class="quoteList"></ul>
<input type="button" onclick="getData();" value="Go Get It!">
<script>
var counter = 0;
window.getData=function()
{
/* This IF block has nothing to do with the OP. It just resets everything so the demo can be ran more than once. */
if (counter===5) {
$('.quoteList').empty();
counter = 0;
}
$.ajax({
/* The whisperingforest.org URL is not longer valid, I found a new one that is similar... */
url:'http://quotes.stormconsultancy.co.uk/random.json',
async: true,
dataType: 'jsonp',
success:function(data){
$('.quoteList').append('<li>' + data.quote +'</li>');
counter++;
if (counter < 5) getData();
}
});
}
</script>
Setting async to false blocks the main thread (responsible for
executing JavaScript, rendering the screen, etc) and waits for the XHR
to complete.
This is almost always a terrible idea. Users don't like unresponsive
UIs. (https://stackoverflow.com/a/20209180/3112803)
Just search stackoverflow for ajax async: false and you will find MANY good explanations on this. Everyone will discourage you from using async:false. Here's is a great explanation: https://stackoverflow.com/a/14220323/3112803
Very interesting methods provided by jQuery when you are executing loops of asyncroniouse request and detect all ajax request completed or not. It is possible by using
var users=["a","b","c","d","e","f","g","h"];
var async_request=[];
var responses=[];
for(i in users)
{
// you can push any aysnc method handler
async_request.push($.ajax({
url:'', // your url
method:'post', // method GET or POST
data:{user_name: users[i]},
success: function(data){
console.log('success of ajax response')
responses.push(data);
}
}));
}
$.when.apply(null, async_request).done( function(){
// all done
console.log('all request completed')
console.log(responses);
});
Here $.when provides a way to execute callback functions based on zero
or more objects, usually Deferred objects that represent asynchronous
events.
apply() converts array elements as different arguments in
function
$.done is call function after all async. request are
completed.
You can use ES6 async/await Promises like this
function fromServer(){
return new Promise((resolve, reject) => {
$.ajax({
url:'http://whisperingforest.org/js/getQuote.php',
async: false,
dataType: 'jsonp',
success:function(data){
resolve(data)
}
});
})
}
var totalQuotes = 0;
async function domManipulation(){
while (counter < 6) {
var data = await fromServer();
$('.quoteList').append('<li>' + data +'</li>');
totalQuotes++;
}
}
domManipulation()
JSFIDDLE
I previously asked about a question using Ajax polling from a server every 3 seconds using the following jQuery Ajax request:
function getData() {
$.ajax({
url : 'http://example.com',
type: 'GET',
success : function(data) {
// process data here
setTimeout(getData, 3000);
},
dataType : 'json'
});
}
It seems that another way of doing this is putting setTimeout outside $.ajax() block:
function getData() {
setTimeout( function() {
$.ajax({
url : 'http://example.com',
type: 'GET',
success : function(data) {
//process data here
},
dataType : 'json'
}) }, 3000);
}
So is there any difference between these two methods? Do they have the same effect of continuous polling the server every 3 seconds?
Also, inside the success callback function, how do I terminate this infinite polling if certain condition is met, say, data.length>1000 then I want to terminate this loop and call another function? Should I do something like this:
function getData() {
var tID = setTimeout( function() {
$.ajax({
url : 'http://example.com',
type: 'GET',
success : function(data) {
//process data here
if(data.length > 1000) {
funcOutside();
clearTimeout(tID);
}
},
dataType : 'json'
}) }, 3000);
}
The second option won't poll every 3 seconds; it will only poll just once.
To conditionally continue or stop polling you should use a variation of the first option: add a conditional around the setTimeout call.
function getData() {
$.ajax({
url : 'http://example.com',
type: 'GET',
success : function(data) {
// depending on the data, either call setTimeout or simply don't
if( /* data says continue polling */) {
setTimeout(getData, 3000);
}
},
dataType : 'json'
});
}
So is there any difference between these two methods? Do they have the same effect of continuous polling the server every 3 seconds?
Yes, there is an important difference! The first version will queue a call to the function after the response arrives. So the interval between calls will be (roughly) 3000ms plus the time the request/response took.
The second version will make a request after 3 seconds, then stop. If you change setTimeout to setInterval, it would make a new request every 3 seconds, but there would be no guarantee the previous request will already have completed when a new one is made (if one request takes ~3000ms). So the first version is probably what you're looking for.
About terminating the loop: yes, just add a condition like the one you have in your code. But instead of clearing the timeout, just don't add a new one:
//process data here
if(data.length > 1000) {
funcOutside();
} else {
setTimeout(getData, 3000);
}
Final note: technically, that's not recursion, because it's not getData calling itself, but the callback from setTimeout calling getData all the time.
(function loopsiloop(){
setTimeout(function(){
$.ajax({
url: 'foo.htm',
success: function( response ){
// do something with the response
loopsiloop(); // recurse
},
error: function(){
// do some error handling. you
// should probably adjust the timeout
// here.
loopsiloop(); // recurse, if you'd like.
}
});
}, 5000);
})();
This will do the work for you.
I'm doing three things here:
Declaring a function loopsiloop that is immediately invoked (notice the parens at the end).
Declaring a timeout handler to fire after 5 seconds.
Polling the server inside the timeout, which upon either success/failure will call loopsiloop and continue the poll.
I want to make an ajax call after every 1 min but the succeeding call should be made only after the preceding ajax call was completed. For example ajax call 2 should be made only after ajax call 1 is completed.
I know how to make a function execute every 1 min with setInterval.
thanks in advance
Try something like this:
(function repeatAjaxCall() {
$.ajax({
url: "example-url.com",
complete: function() {
setTimeout(repeatAjaxCall, 60000)
}
});
})();
Have you taken a look at the Underscore js debounce function?
http://underscorejs.org/#debounce
Basically, these allow you to call a "debounced" version of the function that will not be called until x number of milliseconds since the last call.
This will allow you to do something like this:
var update = _.debounce(function() {
// do some ajax stuff here
}, 300);
setTimeout(update, 1000);
function ajaxCall(){
setTimeout(function(){
$.get( url, function(data){
// do stuff
ajaxCall();
})
}, 60000)
}
As you are saying. If the next call will be fired just when the previous one has finished. And the previous one can delay more than 1 minutes. Let's supose, 2 minutes. So the next one will be called at least within 2 minutes delay. So knowing that. It's ok that will never work minute by minute, right?
So why not call the next ajax when the last one is completed, instead of fire it minute after minute? Using the complete method:
$.ajax({
url: 'file',
type: 'POST',
data: {},
complete: function(xhr, textStatus) {
//CALL HERE THE NEXT AJAX
},
Or if want to give a time of 1 minute after the the previous one is completed:
$.ajax({
url: 'file',
type: 'POST',
data: {},
complete: function(xhr, textStatus) {
setTimeout(function(){
//CALL HERE THE NEXT AJAX
}, 1000)
},
I have a javascript function which supposed to check whether a task is completed.
When the task is completed there is a completion record in a file on the server.
The function supposed to make recursive calls to the server with some delay (potentially increasing) till it gets the completion record in the file.
The code given below makes excessive calls to the server with interval less than a second
example from Web Console:
[20:06:21.202] [20:06:21.563] [20:06:21.990]
But the task becomes competed on variable waittime value getting equal to max_waittime .
Though for a test case overall output is as expected, something is wrong with the function.
Where I'm wrong?
function check_status(time,div_id,filename) {
var status =0;
var waittime=time;
var max_waittime=11000000;
if (waittime < max_waittime){waittime=waittime+1000000; }
$.ajax({
type: "GET",
async: false,
url: "code_on_server_checking_file.php",
data: "f="+filename,
dataType: "text",
success: function(content) {
if (content ) {
// stuff related to output of the result
....
return status=1;
}
else {return status=0;}
}
});
if (status == 0 && waittime < 20000000){
setTimeout(check_status(waittime,div_id,filename),waittime);
}
else {alert('check_status passed!'+status+'|'+waittime);}
}
You need to pass check_status to setTimeout, not the value returned by invoking check_status(...). Since you need to pass parameters to check_status, use an anonymous function:
setTimeout(function () {
check_status(waittime, div_id, filename);
}, waittime);
You are calling the function instead of giving it as a reference to setTimeout. Wrap your function call in an anonymous function. Also, it would be better to simply set up the call in the ajax callback if needed rather than using a synchronous call. A synchronous call will tie up your browser.
function check_status(time,div_id,filename) {
$.ajax({
type: "GET",
url: "code_on_server_checking_file.php",
data: "f="+filename,
dataType: "text",
success: function(content) {
if (content ) {
// stuff related to output of the result
}
else {
time += 1000000;
if (time < 20000000) {
setTimeout( function() { check_status( time, div_id, filename); }, time );
}
}
}
});
}
"recursive calls to the server"? No, I don't think you want that.
If you go three deep, var max_waittime=11000000; will be created and initialized three times.
Maybe you can set the timeout value for the ajax call (ajax settings)
http://api.jquery.com/jQuery.ajax/
First of all, it looks like you don't understand that the ajax call is an asychronous call. Calling it just starts the networking operation and then the rest of your code continues executing. Some time later when the networking operation completes, your success function is called.
The ONLY place you can operate on the results of the ajax call is in the success function. You can't return a value from the success function and expect that to go anywhere. The only place that goes is somewhere inside the ajax code where it's dropped. If you need to do something with the results of the ajax call, then you need to either do that operation right in the success function or call some other function from the success function and pass it the returned data.
These are the parts of your code that do not work:
There's no point in returning the status value from the success function. It doesn't go anywhere except into the ajax function where the return value is just dropped.
This line of code if (status == 0 && waittime < 20000000){ is not doing what you want. Because the ajax call is asynchronous, the value of status has not yet been set by the ajax call when this line of code runs. Thus, it's ALWAYS 0 so your logic never works. You need to move this logic inside the success handler.
As others have said, your parameters to setTimeout are not right. You have to pass a function to setTimeout, not the results of executing a function.
This is the code I would suggest:
function check_status(time, div_id, filename) {
var max_waittime=11000000;
if (time < max_waittime){
time=time+1000000;
}
$.ajax({
type: "GET",
async: false,
url: "code_on_server_checking_file.php",
data: "f="+filename,
dataType: "text",
success: function(content) {
if (content ) {
// stuff related to output of the result
if (time < 20000000){
setTimeout(function() {check_status(time, div_id, filename)}, time);
}
}
}
});
}
Note that all handling of the ajax result is done in the success function and we pass an anonymous function to setTimeout that re-calls check_status after a time delay. This is not actually recursion (as others mentioned) because setTimeout allows check_status to return before it's called again some time later.