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.
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
What is the difference between following snippets
// calling a function
function execute(){
}
function fn(){
asynchronousFunction(function(){
execute();
})
}
fn();
How the below snippet is different from above
// callback a function
function execute(){
}
function fn(done){
asynchronousFunction(function(){
done();
})
}
fn(execute);
In which way callback is different from calling a function directly? What are pros and cons of each approach?
If you call a function, it will execute immediately.
If you pass the function as an argument to another function, then some other code will call it later (at which point it will execute).
They aren't different approaches for doing the same thing. You use a callback when you are writing a function that needs to do something at some point, but when what that something is depends on something outside the function.
The classic example is addEventListener. For the sake of discussion, let's limit ourselves to click events. You have a standard function for making something happen when something is clicked. Lots of programs want something to happen when something is clicked, but that something can be almost anything.
In first case, your function fn() can see execute() and the parameter is optional, because anytime you call fn() will be called execute().
in second case, you made your function more "general" and you may customize your callback function
The first option presents fn as a simple function that starts some kind of asynchronous action and doesn't present any other information to the outside. If fn is something like uploadData, then you'd have a simple function that tries to upload it (and maybe display an error message if it fails, or a success message when it's done), but the caller can only start it and do nothing else.
The second option additionally allows the caller of fn to decide what should happen when fn completes. So if fn is uploadData, then the caller is able to also specify what should happen once the data has been uploaded (or if there has been an error).
Callbacks like these gives you a lot of flexibility. In your second example, you are able to say: "Do fn(), and do the asynchronous function, and if you have finished, then call done()." And the point is, you can decide what done() does, although you have no insight in the method that calls it.
Delivering functions as an argument, that are to be executed e.g. at the begin, at the end or at other events, is a fundamental principle. It is the basis for hooks, callbacks, promises, configuring of complex objects etc.
This question is carefully distilled version of not asynchronous function executed as jQuery Deferred.
We have 2 jsfiddles:
http://jsfiddle.net/XSDVX/1/ - here the progress event is not fired, despite calling notify() function.
http://jsfiddle.net/UXSbw/1/ - here the progress event is fired as expected.
The only difference is one line of code:
setTimeout(dfd.resolve,1);
versus
dfd.resolve();
Questions are:
How is .then catching the .notify that is called before this callback returns when we delay the resolve? Think about it. .then takes the deferred object that was returned from it's first parameter and creates a new deferred object from it, binding to it's done progress and fail events. If the notify was called before the deferred was returned, how is .then catching it even with a setTimeout? (Thanks to https://stackoverflow.com/users/400654/kevin-b for asking this)
Can I get rid of setTimeout() and still have progress callback fired?
Made a big refactor and here is one final working example, with progress monitoring.
Now the important parts.
JQuery deferreds do not execute any progress callbacks, after the resolve has been called (with one exception). In your example (without setTimeout), the deferred is immediately resolved, no chances to run progress.
Do the hooks of all callbacks, especially the progress ones, before we trigger enything on the final Deferred. This is achieved by passing the final Deferred (now beacon) to the execution function, after we have populated it's triggers.
I refactored the API so the func to be executed is deferred agnostic.
This solution, uses a closure of a local (to the reduce iterator function) Deferred, inside the memo.then function, in order to continue the execution chain.
EDIT: I forgot your first question.
This behavior is achieved via the means of a closure (the dfd variable in the "x" function).
The function "x" returns immediately (after triggering a notify event which now can be processed, as all the Deferreds of the execution chain have been created, and the done, fail, progress hooks of the "executePromiseQueueSync" have been hooked).
Also the function of the setTimeout "closes" the dfd in a closure, so it can access the variable despite that the "x" has returned. The "then" call continues by creating the next deferred that is linked to the first one.
After the JS VM yields (it has not other things to do), the setTimeout triggers it's associated function, that (by the means of closure) have access to the "closed" dfd variable. The Deferred is resolved and the chain can continue.
EDIT2: Here is a refactored version that adds support for long executing, deferred supported functions, where they notify their caller for their progress.
EDIT3: Here is another version, without underscore binding and with a jq-ui progressbar example.
By the way this is very good idea for complex app initialization routines.
Source (of the first version)
function executePromiseQueueSync(queue, beacon){
var seed = $.Deferred(),
le = queue.length,
last;
beacon.notify(0);
last = _.reduce(queue, function(memo, ent, ind){
var df = $.Deferred();
df.then(function(){
console.log("DBG proggie");
beacon.notify((ind+1)/le*100);
});
console.log("DBG hook funk "+ind);
memo.then(function(){
console.log("DBG exec func "+ind);
ent.funct.apply(null, ent.argmnt);
df.resolve();
});
return df.promise();
}, seed.promise());
last.then(function(){
beacon.resolve(100)
});
seed.resolve(); // trigger
return beacon.promise();
}
function x(){
// do stuff
console.log("blah");
}
var promisesQueue = [],
beacon = $.Deferred();
promisesQueue.push({funct: x, argmnt:[]});
promisesQueue.push({funct: x, argmnt:[]});
promisesQueue.push({funct: x, argmnt:[]});
function monTheProg(pct)
{
console.log('progress '+pct);
}
// first hook, then exec
beacon.then(function(){
console.log('success');
}, function(){
console.log('failure');
}, monTheProg);
// do the dance
executePromiseQueueSync(promisesQueue, beacon)
I have 3 asynchronous events which can only be run one after the other. When the first asynchronous event is completed, the second is run. When the second event is completed, the third is run. My code is as shown:
asynchronousEvent1(parameters1, function () { // Do stuff
asynchronousEvent2(parameters2, function () { // Do stuff
asynchronousEvent3(parameters3, function () { // Do stuff
});
});
});
This current format means that I need to have long sequences of functions nested within another. Is there some sort of an event handler I could use, for which the format of the code would be approximately:
asynchronousEvent1(parameters1, function () { /* Do stuff */ });
whenEvent1Completed(asynchronousEvent2(parameters2, function () { /* Do stuff */ });
whenEvent2Completed(asynchronousEvent3(parameters3, function () { /* Do stuff */ });
You could use deferred objects introduced in jQuery 1.5. Assuming your functions return deferred objects, like the one returned by $.ajax (or of course you can create your own):
asynchronousEvent1(parameters1).pipe(function() {
// do stuff
return asynchronousEvent2(parameters2);
}).pipe(function() {
// do stuff
return asynchronousEvent3(parameters3);
}).then(function() {
//do stuff
});
Have a look at the last example in deferred.pipe [docs].
I don't necessarily consider this to be an answer, but more of an idea. I don't know how in real life your code is laid out, but would there be the possibility of using an array loaded with the functions to call in their order. Then, it just checks for the next one in the list, and calls that? I don't know would work, but it's an idea.
JMax
I'm not sure I entirely understand what you're looking for.
You can, for example, define a function that handles the results of Event 1, and then simply pass a reference to that function instead of writing the literal at the spot where your chain is defined. If you use that pattern, you'd probably have to tweak how parameters are passed from one event to the second.
E.g.:
function handleEvent1() {
// do something
asynchronousEvent2(parameters2, handleEvent2);
}
function handleEvent2() {
// do something
asynchronousEvent3(parameters3, handleEvent3);
}
asyncronousEvent1(parameters1, handleEvent1);
In this example, none of these event handlers benefit from the same closure as they would in your original implementation, which means you'll need to work out some data visibility stuff.
set a value to true on each event callback and put condition for firing each dependent event.
$('blah').animate({},1000,function(){animated = true}
if(animated){$('blahblah').animate()...}
I am very new to JavaScript and need to use callback function in my java script function. I don't know how to use a callback function. Below is my code:
function SelectedFeature() {
// Here is my code call_Method1();
call_Method2();
}
The problem in the above function is that, call_method2() starts executing before call_Method1() ends its execution. To solve this problem, someone told me to use a callback function. Now how can I use callback function in my SelectedFeature() function? Please explain by using code sample.
I'm making an asynchronous request in call_method1(). I need call_Method2() should be called after completing execution call_method1(). But in my case, call_method2() calls before call_method1() completes its execution. Now how can I fix this?
You have to refactor call_method1() to accept and execute a callback after it finished execution:
call_method1(call_method2);
and
function call_method1(callback) {
// ...
// do asynchronous stuff, when the response is processed, call
if(typeof callback === 'function') {
callback();
}
// ...
}
Functions are first class citizens, so by referring to them by their name, you can pass them around like any other value.
We could help better if you post the code for call_method1.
What are you using to do your asynchronous call? Did you code it yourself or are you using a library like JQuery?
You could simply put a bool to say "working" that you set to true as method 1 starts and back to false when it finishes. you could then have method2 wait while working is true.
The question has already been answered above by Felix. Inspired by his answer and an issue I am having in a current project, I wrote a little gist that has a class that adds up a little extra safety.
To sum up, you pass a callback function just as the way you pass a variable. Then the receiver will trigger it as a function.
myCoolFunction: function( data ) {
// Do some thing with response
}
$.get( '/some/cool/url', myCoolFunction );
In the above $.get calls back myCoolFunction with the parameter data once the data is fetched
What happens if myCoolFunciton is a variable. Well it depends on how the receiver handles the input.
Just to be careful, I have a CoffeeScript class ( and its JavaScript compilation ) that will do some safety checks.
It doesn't do any thing magic, checks if its a function and returns, if not returns an empty function so that it would reduce possibility of JS error. https://gist.github.com/ziyan-junaideen/8717925