This is a simple question, but one i've only seen answered with complex specific examples.
I want to run three functions in order, one after the previous one has finished.
f1();
f2();
f3();
I'm really struggling to do in javascript(/jquery)?! even if i define f1 as:
function f1(){
f1s normal code;
f2();
}
it will still start f2 before f1 has finished its work. I've tried .whens and .done or .thens. I've tried making callback functions with some success. but if someone could cleanly answer this simple example it would help me so much to understand.
thanks in advance!
as long as there is no asynchronous code running in the bodies of the 3 methods, they will always run in order. if you have asynchronous code (ie ajax calls) then you will want to use callback methods.
You need to use callbacks, maybe this helps?
http://jsfiddle.net/2heHs/
Also look at: https://github.com/leesherwood/jquery-function-stack
This is something i chucked up on github. Its not really intended for everyone to use just yet as i mainly needed it for a private project. But if you can make sense of it then feel free to use it. I will be making it cleaner and adding a lot more stuff too it when i get time. Of course you need to be using jquery to use it.
javascript is, by nature, single threaded and sequential. the only way around this is ajax and html5 workers.
that being said, if you want to run three separate functions in order, javascript does that by nature:
var func1 = function () {
console.log('func1 ran');
};
var func2 = function () {
console.log('func2 ran');
};
var func3 = function () {
console.log('func3 ran');
};
// run them in order
func1();
func2();
func3();
http://jsfiddle.net/jbabey/cxxLY/
Related
I realise this is more of a general question, but I've read through similar answers on here but I can't find more of an overview. I'm new to callbacks and I'm trying to understand when they should be used.
The MDN web docs has this example;
function greeting(name) {
alert('Hello ' + name);
}
function processUserInput(callback) {
var name = prompt('Please enter your name.');
callback(name);
}
processUserInput(greeting);
However I'm struggling to see how this is more beneficial than the following, where I'm not passing the greeting function as a parameter?
function greeting(name) {
alert('Hello ' + name);
}
function processUserInput() {
var name = prompt('Please enter your name.');
greeting(name);
}
processUserInput();
As Javascript is async, sometimes it is difficult to handle response from non-blocking functions, for ex. if you are making an ajax call then it'll be executed asynchronously and results will be returned sometime later, by that time the main execution flow will pass the ajax code and starts executing following statements, in that case, its very difficult to catch the response to process further.
To handle those cases, callbacks comes into picture where you pass a function as the parameter to the ajax function and once the response is returned then call the callback by passing response data as a parameter to process further.
more info here http://callbackhell.com/
In simple terms you can say a callback is a way of asking a question (or requesting a task) in advance, i.e. when you're done with this do this (usually with the result). The whole point is to set aside functions that are to be done later, usually because you don't have the required inputs to do them now.
The 2 main differences between your implementation and the MDN one is that yours is harder to maintain and harder to reason about hence test.
1. Maintanance / Reusability
Imagine you're a few thousand lines of code into a code base then you're required to change what processUserInput() does. Its much easier to change or write a new callback function instead of changing the function processUserInput(). This would be evident if processUserInput was a bit more complicated. This also means the MDN one is much more useful in various scenarios unlike your implementation. You can reuse it in different situations like saying good bye, capitalizing names etc simply by writing different callbacks to plug into processUserInput().
2. Testing / Easier to reason about
The MDN implementation is much more easier to understand. Its easier to assume that the function processUserInput(greeting) will probably return a greeting than it is to assume what processUserInput() does. This makes it easier to test because you can always be sure the MDN implementation will always return the same output given an input.
Callbacks can be extremely useful depending on the circumstances; for example, when working with JavaScript for Google Chrome browser extension development, a callback can be used for intercepring web requests once it has been setup.
The purpose of a callback in general is to have the callback routine executed upon a trigger - the trigger being an event of some kind. Usually, functionality follows an interface of chained APIs. By implementing callback support, you can redirect execution flow during a stage of an operation. Callbacks are especially useful to third-party developers when dealing with someone elses library depending on what they are trying to do. Think of them like a notification system.
Functions in general taking in parameters is useful for flexibility and maintenance. If you use different functions for different things, the functions can be simply re-used over and over again to provide different functionality - whilst still preventing bloating the source code with more-or-less the same code over and over again. At the same time, if you use functions to your own library and a bug shows up, you can simply patch it for the one function and then it will be solved.
In your example, your passing a callback routine to the function you're calling - the function you're calling will call the callback function and pass the correct parameters. This is flexible because it allows you to have a callback routine called for printing the contents of the variable, and another for calculating the length of the string passed in, or another for logging it somewhere, etc. It allows you to re-use the function you setup, and have a different function called with the correct parameters without re-making the original function.
This example is not appropriate for understanding callbacks
In simple Language callbacks functions are used when we have to do some stuff after or in response of some other event or function or expression.
i.e when the parent function completes its execution then callback gets executed.
simple Example
function hungerStatus(status,cb){
return cb(status)
}
function whatToDo(status){
return status ? "order Pizza" : "lets play"
}
hungerStatus(false,whatToDo)
Another example
// global variable
var allUserData = [];
// generic logStuff function that prints to console
function logStuff (userData) {
if ( typeof userData === "string")
{
console.log(userData);
}
else if ( typeof userData === "object")
{
for (var item in userData) {
console.log(item + ": " + userData[item]);
}
}
}
// A function that takes two parameters, the last one a callback function
function getInput (options, callback) {
allUserData.push (options);
callback (options);
}
// When we call the getInput function, we pass logStuff as a parameter.
// So logStuff will be the function that will called back (or executed) inside the getInput function
getInput ({name:"Rich", speciality:"JavaScript"}, logStuff);
refer callback exaplanation
I've been trying to read as much as I can about javascript callbacks and jquery deferred objects but apparently things just aren't clicking for me. It seems to make a vague amount of sense when I read through it and practice examples, but when I try to apply it to my specific problem, I'm just hitting a wall. If anyone can understand what I'm trying to do and offer ideas, it would be much appreciated!
Here's some existing code:
$(document).ready(function() {
firstFunction();
secondFunction();
});
For the sake of keeping things simple here, I won't get into what firstFunction() and secondFunction() do, but suffice it to say that they both perform asynchronous work.
Here's my problem:
firstFunction() is dependent on the document being ready so needs to be inside $(document).ready(function() { }. secondFunction() isn't dependent on $(document).ready(function(), but should only execute after firstFunction has completed. I'm hoping to do all the computation for secondFunction() before the $(document).ready(function() { } block, but only execute it after firstFunction() has completed. This way firstFunction and secondFunction will execute in a more visually seamless manner. So basically, I'd like to do something like the following pseudo code:
var deferredSecondFunction = secondFunction().compute().defer(); //perform computation for secondFunction but defer execution
$(document).ready(function() {
firstFunction().done.execute(deferredSecondFunction().execute()); //finally execute secondFunction once firstFunction has completed.
});
Does anyone know if this is even possible? An important caveat is that I need to do this without the Javascript Promise object, since, for reasons outside the scope of this question, the webkit I'm working with is an old version. If anyone could help me understand this it would be appreciated!
The code shown uses a callback function and a self-invoking anonymous JavaScript function such has:
var calculatedObject;
(function(){
// Will be executed as soon as browser interprets it.
// write code here & save your calculations/operations
calculatedObject = { ... };
})();
function firstFunction(callback){
// Do stuff
callback();
}
function secondFunction(){
// Do more stuff
// Use your calculations saved in the calculated object.
}
$(document).ready(function(){
firstFunction(secondFunction);
});
This way the second function will only be called at the end of the first one.
you can use a callback..
function f1(){
//do some stuff
}
function f2(callback){
// do some async stuff
callback();
}
f2(f1);
this example passes one function to another function. the second function then calls the first whenever it's ready.
Let's say for example that I have two functions with random code inside and also that based on the user's system (slow, medium, or fast) there is no way to tell how long the two functions will take to complete, so the use of setTimeout is not practical when trying to fire function2 only after function1 is complete.
How can you use jQuery.deferred to make function2 fire only after function1 no matter what the time requirements are, and considering that both functions are 100% non-jQuery functions with no jQuery code inside them and therefore completely un-observable by jQuery? At the very most, the functions might include jQuery methods like .css() which do not have a time association and can run slower on old computers.
How do I assure that function2 is not executing at the same time as function1 if I call them like this:
function1(); function2();
using $.deferred? Any other answers besides those regarding $.deferred are also welcome!
ADDED March 20:
What if function1() is a lambda function where, depending on user input, the function may or may not have asynchronous calls and it is not possible to tell how many operations the function will do? It'd be a function where you wouldn't have any clue as to what would happen next, but no matter what, you'd still want function2 to execute only after everything from the lambda function (function1) is done, no matter how long it takes but as long as the asynchronous aspects are completed. How can this be achieved?
ADDED March 22:
So I guess the only way to do what I'm asking is to pass anonymous functions as callbacks to asynchromous functions that execute the callbacks after they are done, or to create event listeners that will do execute what you want when the event is finally triggered.
There's not really any way to just execute to asynchronous calls on two seperate lines and have them fire in order without manually constructing mechanisms (event handlers) within the frame containing the said functions to handle the actual execution of their actions.
A good example of these types of mechanisms would be jQuery's .queue() method and $.Defferred object.
The answers below along with reading up on jQuery's API on .queue()ing and using $.Deferred helped clarify this.
Tgr gave a great example below on how to create custom chainable functions using jQuery's $.Deferred object, and the custom functions themselves don't necessarily have to have any jQuery code inside them, which is exactly what I was looking for.
function first(deferred) {
// do stuff
deferred.resolve();
}
function second() {
// do stuff
}
$.Deferred(first).then(second);
But as Tomalak pointed out, this is unnecessary, unless you do something very tricky in first (like utilising web workers).
Update:
The basic idea is that whenever you do something that is not immediate, you create a Deferred object, and return that. (jQuery's AJAX calls already do this.) You can then use Deferred.then to delay follow-up operations.
function first() {
var deferred = $.Deferred();
var callback = function() {
deferred.resolve();
}
// do immediate stuff
someAsyncOperation(callback);
return deferred.promise(); // turns the Deferred into a Promise, which
// means that resolve() will not be accessible
}
function second() {
// do stuff
}
first().then(second); // or: $.when(first).then(second)
If second is also an asynchronous operation, you can use $.when's merging capabilities:
function second() {
var anotherDeferred = $.Deferred();
// do stuff with anotherDeferred
return anotherDeferred.promise();
}
$.when(first(), second()).then(third); // third will run at the moment when
// both first and second are done
JavaScript itself is not asynchronous. It is single-threaded, synchronous.
function1();
function2();
will execute one after another unless they contain asynchronous calls. In that case, there will always be a callback you can pass (like onSuccess for XmlHttpRequest). Place the second function there.
To say the truth, they strictly execute one after another even if they contain asynchronous bits. It's just that the asynchronous bits might not yet be finished when the rest of the function is.
EDIT Your jsFiddle example, fixed (see it):
function foo() {
$('#foo')
.html('<span>foo1</span>')
.animate(
{ /* properties */
left: '100px'
},
360, /* duration */
'swing', /* easing */
function () { /* "complete" callback */
$('#foo').append('<span>foo2</span>');
bar();
}
);
}
As I said. There will always be a callback you can pass.
I'm debugging an app that uses .NET's scriptmanager.
It may be a glitch in firebug, but when I read through the code there are a lot of lines like the following:
// anonymous functions not attached as handlers and not called immediately
function () {
//code
}
// named functions added as methods
myObj = {
myMethod: function myFunctionName() {
//code
}
}
Are these lines valid and, if so, what do they do and what possible reason would there be for coding like this (and I won't accept "It's microsoft - what d'you expect" as an answer)?
This might be worth a read: How does an anonymous function in JavaScript work?
They are there because some busy programmer was intending to do something and ran out of time, but left the stub as a reminder of work to be done. They do nothing as of yet.
or to watermark the code for checks that are done elsewhere in the logic
or simply put there to obfuscate...
I have multiple document.ready functions on a page and I want a function to be called when all my document.ready functions have been executed. I simply want the function to be called
at the very end, after all other document.ready functions have executed.
An example of this could be that each document.ready function increments a global variable when it has been executed, and the last function needs to check the value of that variable at the very end.
Any ideas ?
This will be enough:
$(function () {
window.setTimeout(function () {
// your stuff here
}, 0);
});
This postpones the execution of your function after all other in the document ready queue are executed.
First idea (for small apps): Tidy up
You can just put everything in one $().ready() call. It might nieed refactoring, but it's the right thing to do in most cases.
Second idea: A Mediator [pattern]
Create a mediator class that will register functions and call its register() instead of $().ready(). When all functions are registered You just loop over the collection and run them in the single and only $().ready() and You have a point in code that is just after all is executed.
I am currently developing a kind of a framework for jquery applications that has a mediator. I might stick together a small version including the mediator if You're interested.
Why not just calling it after all the others ?
$(function(){
func1();
...
funcN();
functionThatNeedsToBeCalledAfter();
});
Of course you will have to cleanup your code to have only 1 place where the document ready function is used... but then your code would be more readable so it's worth it.
little hacky but might work, create a variable inside jquery scope like that
$.imDone = false
then create a function with setTimeout called after short time to lookup for the variable ser to true
var theLastFunctionToCall = function(){
alert('I m the last being called!')
}
var trigger = function(){
$.imDone?theLastFunctionToCall():window.setTimeout(trigger,10);
}
trigger();
I only recommend this when u have different $(document).ready in different big js files, but if you can refactor i sincerelly recommend an optimal solution.