I tried to write asynchronous function calls in javascript using setTimeout
function async(fn, callback) {
setTimeout(function () {
fn();
callback();
}, 1000);
}
This is how the function is being called. I want function foo() to run first, and then my next function. Foo() runs successfully but the next function never comes out. Any idea?
async(foo(), function () {
var check = checkField();
alert('Check: ' + check); //somehow never comes out
});
You're calling foo in a synchronous way, because instead of passing a reference to foo to the async function, you're calling foo and passing to async the result of foo, which is probably undefined (although just guessing here, because I don't know how foo looks like), so when the timeout hits and async tries to call fn it throws error that undefined is not a function and thus never reaches the line that calls the second callback.
You should call async this way:
async(foo, function () {
var check = checkField();
alert('Check: ' + check);
});
You should pass foo instead of calling it while calling async:
async(foo, function () {
var check = checkField();
alert('Check: ' + check); //somehow never comes out
});
Related
I have a concern with setTimeout function in javascript. when we call setTimeout function without return anything, it is okay for me. like
setTimeout(function() {
console.log("ok function called")
},2000);
here in the above example it just simply call that function after 2000ms,
And if I write this like
setTimeout(function(params) {
console.log("passed value is"+params)
},2000,55);
now it will call this function with 55 as an argument, right?
But problem is that when I call to write this like
setTimeout(function(params) {
console.log("passed value is"+params)
}(55),2000);
here function is calling with 55 as params but it is now waiting for 2000ms
And when I wrote like
setTimeout(function(params) {
console.log("passed value is "+params);
return function(){
console.log(params)
};
}(55),2000);
in this only return function is calling with 2000ms delay, the line console.log("passed value is "+params); is executing instantly
please help me get out of this problem.
One is a function. Another is a function call.
First, let's forget javascript for now. If you know any other programming language, what do you expect the two pieces of code below to do?
function a () { return 1 }
x = a;
y = a();
What do you expect x to be? 1 or a pointer to function a?
What do you expect y to be? 1 or a pointer to function a?
A function is not a function call. When you call a function it returns a value.
Now let's switch back to javascript. Whenever I get confused by a piece of code, I try to make the syntax simpler so that I can understand what's going on:
setTimeout(function() {console.log("ok function called")}, 2000);
Now, that's a compact piece of code, let's make the syntax simpler. The above code is the same as:
var a = function() {console.log("ok function called")};
setTimeout(a, 2000);
So what does that do? It will call the function a after 2 seconds.
Now let's take a look at:
setTimeout(function() {console.log("ok function called")}(), 2000);
// Note this ----------^^
That's the same as:
var b = function() {console.log("ok function called")}();
setTimeout(b, 2000);
which can further be simplified to:
var a = function() {console.log("ok function called")};
var b = a();
setTimeout(b, 2000);
So I hope you see what you're really passing to setTimeout. You're passing the return value of the function, not the function.
When you write
setTimeout(function (params) { return something; }(55), 2000);
what actually happens is something like this:
var _temp_func = function (params) { return something; };
var _temp = _temp_func(55);
setTimeout(_temp, 2000);
The anonymous function you have as a parameter to setTimeout is evaluated immediately, even before the call to setTimeout itself. In contrast to that, the actual parameter that ends up in _temp here is called with a delay. This is what happens in your last example.
setTimeout takes only function name without parenthesis.
correct syntax : setTimeout(Helloworld) - here you are setting function
incorrect syntax : setTimeout(HelloWorld()) - here you are calling function
or non IIFE function.
It's an IIFE that you are passing hence it is getting called immediately.
setTimeout(function (params) { return something; }(55), 2000);
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);
Lets imagine that I have some code:
var someString = "";
function do1(){
doA();
doB();
}
function doA(){
// some process that takes time and gets me a value
someString = // the value I got in prior line
function doB(){
//do something with someString;
}
What is the correct way to make sure somestring is defined by doB tries to use it? I think this is a situation that calls for a callback, but I'm not sure how to set it up?
Usually, I have solved this problem like following code by callback parameter. However, I don't know this is correct answer. In my case, it's done well.
var someString = "";
function do1(){
doA(doB);
}
function doA(callback){
// some process that takes time and gets me a value
someString = // the value I got in prior line
callback();
}
function doB(){
//do something with someString;
}
I usually write these such that the function can be called with, or without, the callback function. You can do this by calling the callback function only if typeof callback === 'function'. This allows the function which includes the possibility of a callback to be a bit more general purpose. The call to the callback(), obviously, needs to be from within the callback of whatever asynchronous operation you are performing. In the example below, setTimeout is used as the asynchronous action.
var someString = "";
function do1() {
doA(doB); //Call doA with doB as a callback.
}
function doA(callback) {
setTimeout(function() {
//setTimeout is an example of some asynchronous process that takes time
//Change someString to a value which we "received" in this asynchronous call.
someString = 'Timeout expired';
//Do other processing that is normal for doA here.
//Call the callback function, if one was passed to this function
if (typeof callback === 'function') {
callback();
}
}, 2000);
}
function doB() {
//do something with someString;
console.log(someString);
}
do1();
You can, of course, do this without using a global variable:
function do1() {
doA(doB); //Call doA with doB as a callback.
}
function doA(callback) {
setTimeout(function() {
//setTimeout is an example of some asynchronous process that takes time
//Simulate a result
var result = 'Timeout expired';
//Do other processing that is normal for doA here.
//Call the callback function, if one was passed to this function
if (typeof callback === 'function') {
callback(result);
}
}, 2000);
}
function doB(result) {
console.log(result);
}
do1();
function someFunctionA(callback){
var someString = "modify me";
callback(someString);
}
function someFunctionB(someString){
// do something
}
function main() {
someFunctionA(somefunctionB);
}
I am new to javascript and I am trying to understand callbacks. I am not able to understand why 20 is getting printed before 10. My understanding is for a callback function like - func1(parameter,func2()) , func2() is the callback function, which gets executed after func1 executes with the "parameter" passed to func1. Is my understanding correct?
function timePass(length){
console.log("finished after doing timePass for "+length +" seconds")
}
timePass(10,timePass(20));
OUTPUT BELOW:
finished after doing timePass for 20 seconds
finished after doing timePass for 10 seconds
You are not really creating a callback function but actually calling timePass(20) before everything else on your last line of code.
To pass a callback function you should do something like this:
function timePass(length,callback){
console.log("finished after doing timePass for "+length +" seconds")
if(typeof(callback) == "function")
callback(20);
}
timePass(10,timePass);
This is because you execute the function timePass and then - adding the result as argument number 2.
Explaining what is happening:
First you define new function "timePass", The function printing on the console.
Second you execute timePass(10, /*But here you execute it again*/ timePass(20)).
The function timePass(20) will be executed first because you added ().
() == execute. If you just pass the name of the function, it will be passed as function. When you use () it will be executed and then the result will be passed as argument.
EXAMPLE OF USING CALLBACK
function timePass(length, callbackFunction){
console.log("finished after doing timePass for "+length +" seconds");
// check if the function caller is included callback parameter
// and check if it is function - to prevent errors.
if (callbackFunction && typeof callbackFunction == "function") {
// Execute the callback (timePass)
callbackFunction(20);
}
}
// Here you say, Execute timePass with arg 10, and then call timePass
timePass(10, timePass);
// and now callbackFunction defined above will be == timePass
// You can do also
timePass(10, anotherFunction)
// So another function will be executed after console.log()
USE CASES
Most often callbacks are used while we working with async code.
For example: Jsfiddle
// Imagine we have function which will request the server for some data.
function getData(index) {
// The request - response will took some time
// 0.1s ? 15s ? We don't know how big is the data we downloading.
var data;
// Imagine this is an AJAX call, not timeout.
setTimeout(function() {
// after 30ms we recieved 'server data'
data = 'server data';
},30)
return data;
}
var users = getData('users');
console.log(users); // undefined - because we returned "data" before the AJAX is completed.
/*
So we can change the function and adding an callback.
*/
function getAsyncData(index, callback) {
var data;
// Imagine this is an AJAX call, not timeout.
setTimeout(function() {
// after 30ms we recieved 'server data'
data = 'server data';
callback(data);
},30)
}
getAsyncData('users', function(data) {
console.log(data); // 'server data'
});
// OR
function processData(data) {
console.log(data);
}
getAsyncData('users', processData); // processData also logs 'server data'
basically when the interpreter is looking at this, it will call timepass(20) to evaluate the result (which is nothing as you have no return returning something), which then it tries to pass into the outer function.
i.e.
doFunction( doSomethingElse() );
if doSomethingElse returns 1, it must evaluate that before it can pass that 1 into doFunction.
Fundamentally, you have not actually passed a callback, you have called the function. Perhaps you meant:
callback = function() { somecode; }
target = function(data, callback) { console.log('hi'); callback(); }
target(10, callback);
notice the lack of () i.e. callback not callback()
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);
});