How to use jQuery .When .done - javascript

I'm trying to run one function after another function completes.
$.when(saveCanvas(canvas)).done(setWallPaper());
Each function works fine on it's own but when I run the code above it only runs the first function.
What do I need to change?

According to a comment on another SO question, $.when expects deferred objects as arguments. If you don't pass anything, the callbacks will be invoked immediately.
Does setWallPaper() appear to not be working because it is actually being run before saveCancas(canvas)? saveCanvas() is not actually a deferred object, which when expects it to be. To make it a deferred object, add dfr = $.Deferred(); to the beginning of your saveCanvas() function and return dfr.promise(); to the end of it. Check out this SO answer for more details.
function saveCanvas(canvas)
{
dfr = $.Deferred();
//Your code
return dfr.promise();
}
Read more: http://api.jquery.com/jQuery.when/

Looking back at this now, this seems to be how it works with jQuery:
function f1() {
alert("function one");
}
$.when( f1() ).done(function() {
alert("function 1 is done running function two");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Note: This is identical to my method I posted in the question so essentially it should have worked. Though jQuery may have changed over the last 3 years. Most likely was a problem with functions being called.

another wild guess:
$.when(saveCanvas(canvas)).done(function(){
setWallPaper()
});

Related

jQuery deferred ajax execution order

I want to chain multiple functions one after another with promises, and each of the functions make an AJAX call.
something like this:
function myfunction1() {
console.log("myfunction1");
return $.ajax({
url: "/"
}).always(function() {
console.log("myfunction1 done");
});
}
function myfunction2() {
console.log("myfunction2");
return $.ajax({
url: "/"
}).always(function() {
console.log("myfunction2 done");
});
}
myfunction1()
.then(myfunction2());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I would need myfunction1's callback to run before calling myfunction2.
So I would need this order:
myfunction1
myfunction1 done
myfunction2
myfunction2 done
but the code sample runs in this order:
myfunction1
myfunction2
myfunction1 done
myfunction2 done
Any help would be appreciated
Solution:
Parentheses aren't needed
myfunction1().then(myfunction2);
instead of:
myfunction1().then(myfunction2());
thanks #bergi
Since nobody is putting the solution into an answer, I will do so in order to wrap up this question.
Change your code from this:
myfunction1().then(myfunction2());
to this:
myfunction1().then(myfunction2);
You need to pass only a function reference to .then() so it can call the function LATER when the timing is appropriate. When you put the parens after the function name, you were telling the JS interpreter to execute the function immediately and then pass the return result as the .then() handler. That's why it wasn't executing in the desired order.
This is a very common mistake. Just remember that putting parens after a function name causes it to be execute immediately. Passing a function name by itself (without the parens) will just pass a function reference that can be called sometime later by the function/method you passed it to (which is what you want here).
You must need to learn w.r.t promises chaining. You can simply do this.
myFunctionA().then(()=>
return myFunB;
).then(()=> {
//Do stuff after function b execution.`k`
}
I haven't tested that but I hope it will work.
Please accept it as an answer if it works.

Call a function with a variable after other ends (javascript / jquery)

My variable variablex is undefined, how am I supposed to do it right?
Code:
check_content();
function htmlOutput(html){
console.log("first function works")
}
function check_content(){
var variablex = "content";
var html = "foo"
$.when( htmlOutput(html) ).done(function(variablex) {
console.log(variablex);
})
}
JSFiddle
Updated fiddle
You should remove it from the callback done because it will override the variable :
$.when( htmlOutput(html) ).done(function() {
console.log(variablex);
})
NOTE : As #jfriend00 mentioned in the comment bellow there's no reason to use $.when() in your case.
Hope this helps.
Your idea of what to use $.when() for is just wrong. It has no place in this context and thus it does not do what you apparently are expecting it to do.
$.when() requires one or more promises passed to it. It does not have any magical powers to know when some function in it is done.
Plus your htmlOutput(html) function call doesn't even return anything so I have no idea how you expect $.when( htmlOutput(html) ).done(...) to actually have a value.
This explains why your current code does not do what you seem to be expecting. If you want further help, you will have to describe what you're trying to accomplish and why you're using $.when() with a synchronous function that doesn't return a promise.
You can remove the $.when() entirely and just have this because synchronous functions like htmlOutput() block until complete so there's no reason to use promises or $.when() with them:
function htmlOutput(html){
console.log("first function works")
}
function check_content(){
var variablex = "content";
var html = "foo"
htmlOutput(html);
console.log(variablex);
}
check_content();

Jquery deferred - put off a function invocation before previous function is complete

I'm looking for returning objects via promises, I'm looking to make sure that one asynchronous function is fully complete before executing another function.
$.when(firstFunction()).done(secondFunction());
is something like this possible ?
Yes, though because ordinary functions don't return deferred objects, you'll need to make the deferred object yourself.
var dfd = new $.Deferred;
dfd.done(secondFunction);
firstFunction();
...then have firstFunction() resolve dfd (via dfd.resolve()) at the appropriate point. So if firstFunction contains an AJAX request, say, it might look like this:
function firstFunction() {
$.get('some/file.txt').done(function() { dfd.resolve(); });
}

javascript - Order of executing functions

I have some javascript functions being called on Document Ready:
fogFields();
getLoS();
getShips();
startGame();
getNextMove();
However, it is as though getNextMove() is being called first, most likely as all it does is an ajax call and alerts the result. All the other functions have more work, so, the first thing that happens on load is the getNextMove() alert, and in the background you can see that none of the other functions did their work. Until I click OK on the alert window, no results are shown. Can I make it so that until a function finishes, the next wont even start. Some functions call their own extra functions before they finish, and that works in order, but I cant do that with the whole code...
Given the code in your question, there is no way the call to getNextMove can be invoked before startGame has been exited, regardless of their contents.
It may be true that a function that has been scheduled asynchronously (via timeout, AJAX callback etc.) within startGame completes at any time before or after the invocation of getNextMove, but this is a separate issue. To resolve that issue we need to know more about the contents of the functions.
If the other functions have an AJAX call in them, then these AJAX calls most certainly take a callback argument, which is a function that gets executes, when the AJAX call has finshed. Now, if you want to execute your functions in a way, the one function starts when the AJAX call of the previous function finished, you can add an additional callback argument to your own functions, which will then be passed to the AJAX calls. This should illustrate what I mean:
function logFields(callback) {
ajaxCall(callback);
}
function getLoS(callback) {
ajaxCall(callback);
}
function getShips(callback) {
ajaxCall(callback);
}
function startGame(callback) {
ajaxCall(callback);
}
function getNextMove() {
}
fogFields(function(){
getLoS(function(){
getShips(function(){
startGame(function(){
getNextMove();
});
});
});
});
If all of your functions use a ajax call then just use promises.
Simply return it, for example:
function fogFields(){
return $.ajax();
};
and then just use .then:
fogFields().then(getLos());
more information about deffered object on jquery doc page if you use it.
Or implementation in pure javascript you can find here and more theory here.
or another option, which I will not recommend you is to set async param in $.ajax call to false. Again it's for case you use jQuery.

javascript function return not working

I have a problem returning a variable in my function, the below script works fine:
function sessionStatus(){
$(document).ready(function(){
$.getJSON(scriptRoot+"sessionStatus.php",function(status){
alert(status);
});
});
}
sessionStatus();
Bet when I try the following I get a message box with the message "undefined":
function sessionStatus(){
$(document).ready(function(){
$.getJSON(scriptRoot+"sessionStatus.php",function(status){
return status;
});
});
}
alert(sessionStatus());
This is really bugging me, I just can't seem to see what I've done wrong.
There are two things you should know:
1: the JSON thing is asynchronous, so the function call to sessionStatus could already be done when the JSON is still being fetched. The following would work:
function sessionStatus(callback){
$(document).ready(function(){
$.getJSON(scriptRoot + "sessionStatus.php", function(status){
callback(status);
});
});
}
sessionStatus(function(s){alert(s);});
or rather:
function sessionStatus(callback){
$(document).ready(function(){
$.getJSON(scriptRoot + "sessionStatus.php", callback);
});
}
sessionStatus(function(s){alert(s);});
2: even when it would be synchronous, you are only giving a return value from the inner function, so the sessionStatus would return nothing. Check out this code (not related to your JSON thing):
function do() {
var x = 0;
(function(){
x = 2;
})();
return x;
}
or:
function do() {
var x = (function(){
return 2;
})();
return x;
}
Both return 2. Hopefully this explains a bit.
Your function sessionStatus() doesn't return anything, hence the alert says undefined.
All the function does is set thing up for the AJAX call to happen once the page loads - nothing actually happens within sessionStatus() that could be returned.
The code in function(status) { ...} doesn't get run until the AJAX call to the server returns a value, and that AJAX call doesn't get sent until the page loads.
You ought to read up on what $.getJSON() and $(document).ready() actually do, because you're going to continue to get confusing behaviour until you understand them properly.
Your sessionStatus() function never returns anything. It sets a function to run later, and that function returns something, but that's not anything to do with sessionStatus()
You're returning a value when the document ready event is done. Where is your value supposed to go? The jQuery object doesn't know what to do with it.
The function sessionStatus just sets up the event listener for $(document).ready() and then returns without returning a value. That's the undefined you see.
Later when $(document).ready() fires it calls the ajax which if it succeeds returns the status, but nothing is receiving that status.
function sessionStatusCallback(status)
{
alert(status);
}
function sessionStatus(){
$(document).ready(function(){
$.getJSON(scriptRoot+"sessionStatus.php",function(status){
sessionStatusCallback(status);
});
});
}
sessionStatus();
Your function is being called asynchronously -- actually after two asynchronous calls, made via .ready() and .getJSON(). In such a case there is no available return value, instead you have to use a callback, as in the above, to process the response.
Though I should note that the function passed to getJSON in the above already is a callback. You could change that function definition to just be "sessionStatusCallback" and it would call the above callback once the JSON was ready, and you could continue to process there. Or...continue your processing in the current callback (it's a matter of style whether to use a function reference or declare the anonymous function right there in the .getJSON() call)
Functions should never be included in a jQuery(document).ready function. Separate them, so you don´t have side effects you don´t want to have. How do you want to call the session status? And witch function should get the return value?

Categories

Resources