Understanding callbacks in NodeJS - javascript

function firstFunction(_callback){
// do some asynchronous work
// and when the asynchronous stuff is complete
_callback();
}
function secondFunction(){
// call first function and pass in a callback function which
// first function runs when it has completed
firstFunction(function() {
console.log('huzzah, I\'m done!');
});
}
This is an example from this site, I would like help understanding it.
If I have a function that sums 2 number and the other returns it. So:
var z = 0;
function firstf (x, y, callback){
z = x + y;
callback();
}
function secondf () {
console.log(z);
}
I dont get how this works? How do I make it so that secondf waits until firstf is done using callbacks?

After define 2 function, you call:
firstf(2,3,secondf);
Follow : z=2+3 then call function callback. And now, function callback ~ secondf :
z=2+3 ;
secondf();

If you want to the second block to wait until the first block is done. Then using callback makes no sense.
Because the main concept of callback is to provide an asynchronous platform.
A callback is a function call at the completion of a given task, hence prevents any blocking which may might occur if the first block takes long time to load data.
So, if you want both the blocks to work asynchronously the use callback, and to achieve what you are asking simply call the second function after the task of block one is done.
For better understanding go through this link,
https://docs.nodejitsu.com/articles/getting-started/control-flow/what-are-callbacks/
Best of luck!

You can use "promise" concept to ensure that the secondf waits until firstf is done:
function firstf(x,y){
return new Promise(
function (resolve, reject) {
resolve(x+y);
});
}
function secondf(){
firstf(x,y).then ( function (result){
console.log(result);
});
}

By re-ordering your code:
edit Made code async for demo purposes
var z = 0;
function firstf(x, y, callback) {
console.log("Inside firstf");
z = x + y;
console.log("Will call callback in 1 second");
// Lets make this function async.
setTimeout(function() {
console.log("Calling callback");
callback();
}, 1000);
}
function secondf() {
console.log("Inside secondf");
console.log(z);
console.log("Leaving secondf");
}
firstf(1, 2, secondf);

Related

numerous nested functions in javascript

I've been reading about async functions in JavaScript and found out that I don't quite understand the following piece of code that comes from here.
Here it is:
doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log('Got the final result: ' + finalResult);
}, failureCallback);
}, failureCallback);
}, failureCallback);
What I don't understand is where all these results come from.
They are callbacks. A callback is just simply a function which is passed as an argument to another function and is used to do something with the result of some operation done by the function which receives the callback as an argument. You can write your own. A simple example:
function callMe(callback) {
let addition = 2 + 2;
callback(addition);
}
callMe(function(result) {
console.log(result);
});
callMe calls its callback function with the result of 2 + 2. You then receive that result inside the callback function when you use callMe, and you can then write your own custom code to do whatever you want with it.
The beauty of JavaScript is that you already have all you need to test it.
The code you posted references 4 functions (don't forget the failure callback):
doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log('Got the final result: ' + finalResult);
}, failureCallback);
}, failureCallback);
}, failureCallback);
Those functions are not written. So let's write them:
var failureCallback = function() {
console.log('something went wrong');
}
var doSomething = function(callback) {
window.setTimeout(function() {
var result = Date.now(); // Create some data that will change every time the function is invoked
callback(result);
}, 500);
}
var doSomethingElse = function(res, callback) {
window.setTimeout(function() {
var result = [res]; // all this function really does is put the first argument in an array
callback(result);
}, 500);
}
function doThirdThing(res, callback) {
window.setTimeout(function() {
res.push(Math.PI); // res is supposed to be an array, so we can add stuff to it.
var result = res;
callback(result); // here we could have used res as a value, but I kept it consistent
}, 500);
}
doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log('Got the final result: ', finalResult); // switched to a comma to display properly in the console
}, failureCallback);
}, failureCallback);
}, failureCallback);
To create some asynchronicity I used setTimeout so overall you have to wait 1.5 seconds.
The 3 functions that use a callback function as an argument, simply execute the function they were given. This is absolutely standard in JavaScript where functions are first class objects: you can pass them around as arguments like any other value type.
Javascript is a single threaded language, callbacks are used as a way to control the flow of execution when a asynchronous block of code ends in a non-blocking way. A callback is normally just another function (function B) that is passed into the asynchronous function (function A) to run when function A completes. I.E
doSomething(func) {
// do async code.
// call func
// func()
}
you haven't posted the inner blocks of those functions but i think we can all safely assume "result" is the response from the server passed back into the callback function I.E
doSomething(callback) {
//fetch or ajax or whatever to server store response.
//pass response BACK to callback function
callback(response)
}

Simple but difficult. How to force external libs functions run sequentially?

If we have two function in javascript, one slow and one fast. For example:
function slow() {
setTimeout(function() {console.log("slow finished")}, 10000);
}
function fast() {
console.log("fast");
}
And these functions don't have inside of them new structures like promisses (if we do not implement after).
How can we force these functions run in order? For example:
function run() {
slow();
fast();
}
run();
How can we force fast wait slow finishes?
I'm looking a solution that could work inside mobile application browsers, becase of a Apache Cordova project of mine.
Is there a way to do this?
An idea of mine is inject a callback function between the functions.
And this callback is called at the end of the slow function, calling the fast function.
An important thing is I can't (or would not) rewrite the code of the slow and fast functions,
because they will reside inside external libraries.
I'm looking for a solution to countorn this problem as an external observer and manager.
How can we do this?
Edit
He I was a trying to solve the problem merging the answers. No success yet.
I had changed slow but this is not really allowed. I have changed it to se what is happening with a. I couldn't get something interesting because a becomes undefined immediately and not after slow finishes...
var a = "adsfadsfadsf";
function slow() {
setTimeout(function() {console.log("slow done"); console.log("a2", window.a);}, 3000);
}
function fast() {
console.log("a3", window.a);
console.log("fast done");
}
var newSlow = function() {
return new Promise(function(resolve, reject){
window.a = slow();
console.log("a", a);
resolve("Sucess");
});
};
newSlow().then(function(resolve){fast();}, function(reject){console.log("error");});
I have tried with resolve(slow()); no sucess too.
That's a very interesting question. Well I can think of a way where if it is changing some global variable "g" to some value say "true". In that case if you can run them sequentially as,
<script>
var g = false;
var i;
function slow() {
setTimeout(function() {console.log("slow finished");g=true;}, 10000);
}
function fast() {
console.log("fast");
}
function run() {
slow();
i = setInterval(function(){check();},1000);
}
function check(){
if(g){
fast();
clearInterval(i);
}
}
run();
</script>
As in this demo
UPDATE: Something just struck me and I guess we might be able to add a callback function to slow() even if we can't access it directly.
If a function is called without parenthesis then the entire function as a content is returned as a string so we can edit that string by adding fast() to it registering that string as a function using eval().
function run() {
var myFun = slow+"";
myFun = myFun.substring(0,myFun.length-1);
alert(myFun);
myFun += "fast();}";
//to register the string "myFun" as a function
eval(myFun);
slow();
}
So basically our slow() function becomes,
function slow(){
//function code
//the appended function
fast();
}
NOTE: This will not worked in the example given above where GarouDan has deliberately added setTimeout limit to recreate a scenario where the slow() function takes longer time than the fast() function. However, in a real-world scenario I'm sure this approach would definetly work.
You could use the Promise pattern.
Promises are tailor made for situations where various parts of code may run slow or fast or complete in unknowable amounts of time (or not complete at all), while still giving you execution control.
My personal favorite library that implements the Promise pattern is RSVP.
Here is some pseudocode to give you the idea. Run an operation that may take a long time, then run one only when the first has either completed, or handle it's failure.
function doFoo() {
var promise = new RSVP.Promise(function(resolve, reject) {
// do some long-running operation, like retrieve
// data from a slow site...
if (data.Status && data.Status === 200) {
resolve(data);
} else {
reject(data.Error)
}
});
return promise;
}
function doBar() {
var promise = new RSVP.Promise(function(resolve, reject) {
// do some fast operation, like count to 10
for (i = 0; i < 10; i++) {
console.log(i);
}
resolve("");
});
return promise;
}
Now you can call:
function inOrder() {
doFoo().then(function(success) {
doBar();
}).catch (function(failure) {
console.log("oops! " + failure);
}
});
}
This runs doFoo, and ONLY runs doBar after doFoo has completed successfully. Note that you could also run doBar even if doFoo has failed.

wait for function done (with setInterval) and run next function

how to run next function after first done with setInterval?
for example:
step1();
step2();
setInterval(step1, 1000).done(function() {
setInterval(step2, 1000).done( /* next step */);
});
please help me with solution!
Edit: This is an old answer. Now you can achieve this using promises also but the code will be slightly different.
If you don't want to use a promise you can use a simple flag to achieve such a thing. Please see example below:
var flag = true;
function step1() {
console.log('title');
}
function step2() {
console.log('subtitle');
}
function wrapper() {
if(flag) {
step1();
} else {
step2();
}
flag = !flag;
}
setInterval(wrapper, 30000);
If you want to chain functions on completion you can use callback functions.
Example:
function first(callback) {
console.log('Running first');
if (callback) {
callback();
}
}
function second() {
console.log('Running second function');
}
first(second);
The first function checks if a callback is used and then runs it. If there is no callback function nothing happens. You can chain functions this way.
You can also use anonymous functions.
first(function () {
console.log('This function that will run after the first one);
});
If you use setTimeout() you can't be sure whether the previous function has completed. A better way would be to use promises.
Understanding Promises
I hope I understood your question right. Good luck!
First of all setInterval can not be done by itself, it will fire infinitely if you not clear it with clearInterval.
But if you have some async action inside your function and whant to wait for it and then call another function you may just promisify it like Avraam Mavridis suggested.
function step1() {
var deferred = $.Deferred();
setTimeout(function () {
alert('I am step 1');
deferred.resolve();
}, 1000);
return deferred.promise();
}
function step2() {
alert('I am step 2');
}
step1().done(step2);
JsFiddle

Calling a function after another function's callbacks are returned

This is the simplified version of my problem:
var callback_one = function (result_from_web_service) {
console.log('callback one');
};
var callback_two = function (result_from_web_service) {
console.log('callback two');
};
// the async_calls are library calls that i don't own or modify
var x = function () {
console.log('x is called');
async_call_one(callback_one);
async_call_two(callback_two);
};
var y = function () {
console.log('y is called');
};
Test:
x();
y();
// prints: 'x is called', 'y is called', 'callback one', 'callback two'
// what i need: 'x is called', 'callback one', 'callback two', 'y is called'
What I did to accomplish this was calling y() inside call_back_two:
var callback_two = function (result_from_web_service) {
console.log('callback two');
y();
};
But now my use case requires that y be called outside of the callback (will be called by the user of my code). i.e. the calling of x() and y() be independent in a way that the calling of x() doesn't end up calling y(). y() should be called independently but only if x() and its callbacks are processed. think of x() as like creating an object in java and y() as a method you would call whenever you want.
//.. some code, x() does some kind of initialization...
x();
// OPTIONALLY call y(), but make sure x() and its callbacks are processed
y();
I tried the below but doesn't work.
$.when(x()).then(y());
Thanks,
The only way to make something like this work properly is to make y asynchronous. Basically, y internally waits for x to complete before executing its own code. This is similar to things like domready or onload which waits for other things to happen before executing their own logic.
There are two ways to accomplish this. The first, simplest and most naive way is setTimeout polling. Make x set a variable or attribute and check that before executing:
function y () {
if (x.ready) {
/* do what you need to do here */
}
else {
setTimeout(y,100);
}
}
The second method is to create virtual events or promises. Not all promise libraries support using a promise that has already expired (my own homemade one does) so you may need to write your own control flow to handle that case. For this you need to rewrite x to support an event or promise-like api:
var x = (function () {
var async_calls = 2;
var callback;
f = function () {
console.log('x is called');
async_call_one(function(){
async_calls --;
if (async_calls == 0 && callback) callback();
callback_one();
});
async_call_two(function(){
async_calls --;
if (async_calls == 0 && callback) callback();
callback_two();
});
}
f.loaded = function (loaded_callback) {
callback = loaded_callback;
if (async_calls == 0) callback();
}
return f;
})();
Now in y you can use the x.loaded function to execute your code when x is loaded:
function y () {
x.loaded(function(){
/* do what you need to do here */
});
}
Of course, this has the problem of making y asynchronous. Therefore if your users expect to write something like:
y();
a();
b();
then a and b may or may not execute before y. To solve this you need to make y accept a callback so that you users can control their program flow:
function y (callback) {
if (x.ready) {
/* do what you need to do here */
callback();
}
else {
setTimeout(function(){y(callback)},100);
}
}
or:
function y (callback) {
x.loaded(function(){
/* do what you need to do here */
callback();
});
}
So they'd have to use y like this:
y(function(){
a();
b();
});
Alternatively you can make y return a promise if you prefer that style.
A little bit down the road to spaghetti code but you could wrap up the two callbacks together by setting variables they both can see and only call y() when they both return.
for example
var finished = false;
var aync_call_one = function () {
//stuff
if (finished) {
y();
} else {
finished = true;
}
}
var aync_call_two = function () {
//stuff
if (finished) {
y();
} else {
finished = true;
}
}
However if you have to use jquery promises, you need to return a promise object to use $.when,
var deferred = $.Deferred();
return deferred.promise();
and inside the asyncs you need to do
deferred.resolve();
though that would only work for one of your async calls so you would need another $.when inside the first function, so it can get sloppy quick.

Asynchronous call in javascript

I am executing a function and i want to pause execution for some time.
function a(){
}
//here some code --- I am using result of a function here...
Can anyone help me... how to use asynchronous call??
Your function should accept a callback parameter that it would execute after doing its thing. So something like:
function a(callback) {
// do something
if (callback) {
callback();
}
}
Then you would call it like:
a(function () {
alert("finished");
});
How about just using
setTimeout(function(){
// do some work after the timeout pause
}, 1500);
It is waiting for 1500 milliseconds before executing the function contained.
Not sure what you mean - to use result of a function, assign it to a variable:
var r = a();
//....some code...
//using result of a function here
alert("result of a(): " + r);
In case of AJAX or something similar use the callback function provided to you, for example with jQuery:
$.post("myajaxpage", function() {
//callback function - executed after request is finished
var r = a();
alert("result of a(): " + r);
});

Categories

Resources