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

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();

Related

Javascript - return a value or use a callback function

I am curious what is considered the better style/the correct way to do something.
In javascript, I could do the following:
function one() {
two(param, function(ans){
// do more work
});
}
function two(param, callback) {
var answer;
//do work
callback(answer);
}
but I could have a similar result by simply returning the answer:
function one() {
var ans = two(param);
// do more work
}
function two(param, callback) {
var answer;
//do work
return answer;
}
I think that if all you need is "answer" then it is probably better to use the second version and just return that value rather than passing a callback function as a parameter, etc. - is my thinking correct? Any ideas on the relative performance of the two? Again, I would expect the return version to be better performance-wise.
Generally a callback function is used when the function you are calling will be performing an asynchronous event (such as making an AJAX call) that will be done in a non-blocking fashion.
Non-blocking means that once you call that function, your code will continue on to the next statement BEFORE the function you just called has completed its work. Hence the callback function, in which you put code that you want to be executed AFTER the non-blocking function has completed.
I would recommend returning answer directly from two rather then implementing a callback. Too many callbacks can lead to what is known as the Callback Pyramid
You should use the return.
Callback are suitable when you perform asynchronous actions, otherwise they're useless overhead.
You should definitely just use return. Callbacks are meant for when you would like some customized code to be executed after the completion of a function or an asynchronous event such as an Ajax call.

Multiple functions on form submit jQuery

I have to call two functions on form submit but i want to make sure that that second function is executed only after the first function is executed.
I do not have control over the first function, so i cannot edit it at all.
function a(et){
//function a script
}
function b(evt){
//function b script
}
from function b is there a way that i can check if function a was completed or executed fully.
if you have no access to a at all then you can't do what you want to do here. No way: JS creates a call object when a function is called, and auto-GC's it when the call is complete. Sadly, the actual mem-management is off limits, so you can't check that. other trickery involves your meddling with the code of function a, which you say you cant get at... so no, you can't do this.
Sorry for that, but it's as the FAQ says: you might not always get the answer you're hoping for, but that doesn't mean the answer you don't like isn't true... :-P
There is, however, a little bit of hope for you: if both function a and b are callbacks or handlers of a submit event, you could look into ways of queueing those calls. Given the jQuery tag .queue() suggests itself
According to Eli Grey you can tested like this:
function foo() {
foo.complete = false;
// your code here
foo.complete = true;
}
foo.complete = false;
if (foo.complete) { // foo execution complete
// your code here
}
Yes, you can, there is a lot of ways to do that, but here is a simple way to make it.
You can use persistent object localStorage.
You can use session object sessionStorage.
function a(evt){
// Asynchronous function
// ... your code here
// before finish function create the persistent object
localStorage.setItem('myObject', 'done');
return;
}
function b(evt){
// Checks if a() function was completed
var _done = localStorage.getItem('myObject');
if(_done && _done == 'done') {
// your code here: the a() function was completed
localStorage.removeItem('myObject');
}
}

How to use jQuery .When .done

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()
});

Best practice for code after callback

Here's what I'm trying to do.
I'm currently using node.js and one of the things it allows you to do is:
socket.on("sometopic", function() {
// this is a callback
}
Now let's say I have 10 different topics, each of these with one corresponding handling function that I keep in my "window", as such:
windows.callbacks["topic_a"] = function() {
// code for cb a
}
windows.callbacks["topic_b"] = function() {
// code for cb b
}
windows.callbacks["topic_z"] = function() {
// code for cb z
}
And there's a piece of code I would like to have executed at the end of every callback. An easy way out is to create a function with this code and add a call at the end of each callback but this is far from being elegant.
Can anyone suggest a better solution for this? Is there a best practice that I'm unaware of? I'm fairly green to this kind of functional programming.
// THIS IS AN IDEA
// helper
function teardownWith(fn){
return function (cb){
return function(){
return (cb(), fn());
};
};
}
// prepare a modified function
var endWithDate = teardownWith(function(){
log(Date());
});
// pass our callback into the modified function
// endWithDate() returns the final callback.
window.callbacks["cb_a"] = endWithDate(function(){
// code for cb_a
});
Consider using the jQuery Deferred object, and adding a method to execute 'always'
jQuery Deferred Object Documentation

What does this.async() do in JavaScript

Kept on seeing this pattern in code, but couldn't find any reference to it in google or SO, strange. Can someone point me to reference for this.async() function?
var done = this.async();
// ...
$.get(path, function(contents) { // or some other function with callback
// ...
done(JST[path] = tmpl);
})
var done = this.async() and done(blah) is a clever trick to return a value fetched from asynchronous call (e.g. $.get) within a synchronous function.
Let's see an example:
var getText = function() {
return "hello";
};
var text = getText();
It's a pretty straightforward function call so no puzzle here. However, what if you need to fetch the text asynchronously in getText() function?
var getText = function() {
return $.get('<some-url>', function(text) {
return text;
}); // ??????
};
call to getText() doesn't return the text you want to get. It returns jquery's promise object.
So how do we make getText() return the text it gets from $.get() call?
var getText = function() {
var done = this.async();
$.get('<some-url>', function(text) {
done(text);
});
};
var text = getText(); // you get the expected text
Magic, right?
I don't know the inner-working of this.async() call yet. I don't know if there is a library provides that function, but you can see that Backbone.LayoutManager uses this trick https://github.com/tbranyen/backbone.layoutmanager/blob/master/backbone.layoutmanager.js (search for this.async).
Also, Tim Branyen (the author of backbone layoutmanager) briefly talks about it in his video tutorial (http://vimeo.com/32765088 around 14:00 - 15:00). In the video, Tim says Ben Alman came up with that trick. Take a look at this as well https://github.com/cowboy/javascript-sync-async-foreach
I think it's a pretty neat trick to mix async and sync functions.
Cheers,
var done = this.async() is a pattern used in Grunt to help perform asynchronous functions within a Task.
You need to invoke done() or done(returnValues) to tell Grunt the task is complete (after your chain of asynchronous tasks).
Read more about it:
https://gruntjs.com/inside-tasks#inside-all-tasks
It is a way to work around the problem of this escaping inside callback. Without this extra reference the code would look like this:
$.get(path, function(contents) { // or some other function with callback
//Wrong! `this` might no longer point to your object
this.done(JST[path] = tmpl);
})
Unfortunately! this inside response callback is not the same as this outside of it. In fact it can be anything, depending on what $.get (calling the callback using) decides it to be. Most of the people use extra reference named that for the same purpose:
var that = this;
// ...
$.get(path, function(contents) { // or some other function with callback
// ...
that.async(JST[path] = tmpl);
})
This pattern also seems reasonable and readable.
Oh, and if you are curious about this syntax:
done(JST[path] = tmpl)
This is an assignment used as an expression. The value of assignment is the right-hand side, so this code is equivalent to:
JST[path] = tmpl;
done(tmpl);

Categories

Resources