Deferring Callback until setTimeout has Completed - javascript

I have searched everywhere for a solution to this but have not been able to find anything thus far (I am probably using the wrong keywords! If this is a duplicate, please point out and I will delete).
Could one of you brilliant SO geniuses kindly explain to me why the following does not work as one would hope? What I mean by this is the complete callback is called before the setTimeout has completed within the success callback and I don't quite understand why.
$.ajax({
url: options.url,
data: options.data,
success: function(){
setTimeout(function(){
console.log('firing');
},2000);
},
dataType: options.dataType,
complete: function(){
console.log('ended');
}
});
Is it because a new thread has been started by the setTimeout within the success callback?
Is this possible to achieve without passing in a callback function into the success callback?

It happens because setTimeout() does not block the execution of code.
Therefore the complete callback fires at the same moment as it would without your call to setTimeout().
You will have to put your console.log('ended'); call into a timeout (too) or call your complete handler inside the timeout. :)

Related

setTimeout behavior with jquery and ajax

It is my understanding that setTimeout() can be used to stop code from executing temporarily, however this doesn't seem to be the case in the following code:
...}).done(function recursionLoad(){
var timerLoad = setTimeout(function(){
},3000)
$.ajax({
type:'GET',
url:'modelBN.xml',
beforeSend: function(){$('#query-results').html('<img src="images/ajax-loader.gif"><p>Loading...</p>'); },
timeout: 10000,
error: function(xhr, status, error){...
So what happens is the AJAX call get made immediately instead being delayed for 3 seconds. Am I just using setTimeout incorrectly or is there something about AJAX that prevents it from working? Thanks for any assistance
setTimeout will call the function you pass to it (in the first argument) after the time you specify in the second argument.
It is not a sleep function, and it won't block other code from running.
If you want to run your call to $.ajax after the time has elapsed, then you need to do so from the function you pass to setTimeout (as opposed to calling setTimeout (with a function that will do nothing after 3 seconds) and then immediately calling $.ajax).

how do i callback with js function [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
I'm having trouble with callbacks mainly because I don't understand how they're working (or supposed to work).
I have my function:
function checkDuplicateIndex(values, callback) {
$.ajax({
type: "POST",
url: url,
data: "command=checkIndexAlbumTracks&" + values,
dataType: "html",
success: function(data){
var returnValue = data.d;
callback(returnValue);
}
});
}
And then within a submit event, how do I properly call checkDuplicateIndex so that I can alert() the value?
This ended up being a long answer, so I'm going to try to split it into pieces.
Functions in Javascript
So within javascript, a function is an object that can be passed around, assigned to a variable, etc, just like any other data type. The difference is that a function, rather than being a string of text, number, etc, is a block of code waiting to be executed.
This is often confusing to people starting out with programming because usually when you write code, it is executed when you run the program. But for functions, this is not the case. When you write code inside a function, it waits there not executing until you call the function. If you do not call the function, the code is never executed. Let's check out a quick example:
function say_hello(){
console.log('hello!');
}
What you see here is called a function declaration. This means you are creating a function, which is a block of code waiting to be executed. If you run this code, nothing will be logged to the console. Now let's look at a function call.
function say_hello(){
console.log('hello!');
}
say_hello();
So here we declare the function just like before, but below we call it. A function call is just the name of the function followed by open and close parens. If the function takes arguments, they will be inside the parens, but no need to worry about that for now. If you were to run this code, you would in fact see hello! logged to the console, because the function was called, which executes the code inside.
Asynchronous Code
Now, let's switch gears for a second. When you make a jquery ajax call, jquery abstracts a lot of code into the library. They take care of setting up the XMLHttpRequest, firing it off to the place you specify, and collecting the result, and they do this in a way that works cross-browser. But since javascript is asynchronous, as soon as the ajax call goes off, javascript keeps executing code after the ajax call, because who wants to wait around for someone else's server to respond while you could be still getting in that work. So if you fire off something like this:
$.ajax({
url: 'http://google.com',
success: function(){ console.log('done!') }
});
console.log('after ajax call');
...you may be surprised to find that it logs after ajax call before logging done!. This is because, as stated earlier, in javascript calls that deal with I/O are often asynchronous.
So if the ajax call is made and it immediately continues executing code even if the ajax call has not finished, how can we specify code that will run when it's finished? This is where everything comes together. By providing jquery with a function, which as we remember is a block of unexecuted code, we can provide a way for ourselves to write code that is executed only after the ajax call has finished by passing the block of unexecuted code to jquery and saying essetially "hey jquery, take this code, and when the ajax call is finished, call it and pass in any data you got out of it." How convenient!
The way we do this is through the success and error properites of jquery's ajax function. If the request was successful, it will call the function we pass to success, and I assume you can guess what happens if there was an error.
Putting It All Together
Asynchronous code and first class functions are two of the most confusing parts about javascript, and once you understand these two concepts, you'll be in a great spot, although it may take a while to get there. So it's important to think carefully about it and experiment. Let's talk through a couple ways to handle the example you are working with here, about jquery ajax.
First, we can try making our own function and passing the name of the function to the success handler. Then when it comes back, it will call the function. Let's take a look:
var my_callback = function(data){
console.log(data);
}
$.ajax({
url: 'http://google.com',
success: my_callback
});
This is an interesting way of doing it. Here we have assigned an anonymous function to a variable, then passed the variable name to the success handler. This will work fine. Now let's try another way:
function my_callback(data){
console.log(data);
}
$.ajax({
url: 'http://google.com',
success: my_callback
});
Here, we define a named function and do the same thing. This will work the same way. Named functions in javascript can actually be declared after the are used, so you could move the function declaration below the ajax call and it would still work. Try this out. This is a nice advantage to named functions.
Finally, let's take a look at a third way we could handle it:
$.ajax({
url: 'http://google.com',
success: function(data){
console.log(data);
}
});
Here, we define an anonymous function right inline on the success handler. This works exactly the same as either of the other two options. In all three of these ways, jquery receives a function declaration, and calls it when it needs to, which is after the ajax request has come back.
I know this is a super long answer, but what you are confused about here are some of the core concepts of javascript, and I thought it would be more helpful to go over them here than to just solve your problem and give you the answer without explanation of the concepts. In fact, I haven't actually tackled your problem here at all, but you will easily be able to solve it yourself after understanding these concepts. If you are still having trouble, drop a comment and I'll try to clarify more.
Given the above code, you would call it like this within your submit handler:
var values = '…';
checkDuplicateIndex(values, function(returnValue) {
alert(returnValue);
// additional processing here...
});

Continue function after ajax request has been completed

I was wondering if it was possible to have a function call a function that has an ajax request, and continue executing when the ajax request finished. Here is example pseudo code.
function func1(){
//do things
func2();
//**How would I get this code to execute after the ajax request is finished.
}
function func2(){
$.ajax({
url: "test.html",
context: document.body,
success: function(){
//do some things
}
});
I do not want to execute everything in a callback function, as this function is called many times in a loop.
Thanks!
You have two choices.
Use a callback function for the processing that happens after the AJAX call.
Use a synchronous "JAX" call ... remember, the A in AJAX is Asynchronous.
Otherwise, there's not a good way to accomplish what you describe.

Wait for function to finish before executing the rest

When the user refreshes the page, defaultView() is called, which loads some UI elements. $.address.change() should execute when defaultView() has finished, but this doesn't happen all the time. $.address.change() cannot be in the success: callback, as it's used by the application to track URL changes.
defaultView();
function defaultView() {
$('#tout').fadeOut('normal', function() {
$.ajax({
url: "functions.php",
type: "GET",
data: "defaultview=true",
async: false,
success: function (response) {
$('#tout').html(response).fadeIn('normal');
}
});
});
}
$.address.change(function(hash) {
hash = hash.value;
getPage(hash);
});
I'm at a loss as to how to make $.address.change() wait for defaultView() to finish. Any help would be appreciated.
Call it in the success or complete callback. Using delay for timing a callback is unreliable at best. You might even need to put the call to it in the callback to the fadeIn function inside of the success callback.
It doesn't have to be defined inside the success callback, just executed. Both contexts will still be able to use it.
I too was told that because of async you can't make javascript "wait" -- but behold an answer :D ...and since you're using jQuery, all the better:
use jQuery's bind and trigger. I posted an answer to a similar problem at How to get a variable returned across multiple functions - Javascript/jQuery
One option is to hide the $.address (I'm guessing this is a drop-down list) via css, and show it inside the success callback from the ajax method.

Javascript: Trigger action on function exit

Is there a way to listen for a javascript function to exit? A trigger that could be setup when a function has completed?
I am attempting to use a user interface obfuscation technique (BlockUI) while an AJAX object is retrieving data from the DB, but the function doesn't necessarily execute last, even if you put it at the end of the function call.
Example:
function doStuff() {
blockUI();
ajaxCall();
unblockUI();
};
Is there a way for doStuff to listen for ajaxCall to complete, before firing the unBlockUI? As it is, it processes the function linearly, calling each object in order, then a separate thread is spawned to complete each one. So, though my AJAX call might take 10-15 seconds to complete, I am only blocking the user for just a split-second, due to the linear execution of the function.
There are less elegant ways around this...putting a loop to end only when a return value set by the AJAX function is set to true, or something of that nature. But that seems unnecessarily complicated and inefficient.
However you're accomplishing your Ajax routines, what you need is a "callback" function that will run once it's complete:
function ajaxCall(callback){
//do ajax stuff...
callback();
}
Then:
function doStuff(){
blockUI();
ajaxCall(unblockUI);
}
Your AJAX call should specify a callback function. You can call the unblockUI from within the callback.
SAJAX is a simple AJAX library that has more help on how to do AJAX calls.
There's also another post that describes what you're looking for.
You can do a synchronous xhr. This would cause the entire UI block for the duration of the call (no matter how long it might take).
You need to redesign your program flow to be compatible with asynchronus flow, like specifying a callback function to be called after the response is processed. Check out how Prototype or JQuery or ... accomplishes this.
The answer is simple, you have to call unblockUI() when your ajax request returns the result, using jQuery you can do it like this:
function doStuff(){
blockUI();
jQuery.ajax({
url: "example.com",
type: "POST", //you can use GET or POST
success: function(){
unblockUI();
}
});
}
It sounds to me that you want the user to wait while info is being fetched from the db. What I do when I make an Ajax call for some info from the database is to display an animated gif that says "getting it..." - it flashes continually until the info is retrieved and displayed in the webpage. When the info is displayed, the animated gif is turned off/hidden and the focus is moved to the new info being displayed. The animated gif lets the user know that something is happening.

Categories

Resources