I have been trying to figure out the Callback function feature in Javascript for a while without any success. I probably have the code messed up, however I am not getting any Javascript errors, so I supposed the syntax is somewhat correct.
Basically, I am looking for the getDistanceWithLatLong() function to end before the updateDB() begins, and then make sure that ends before the printList() function begins.
I have it working with a hardcoded "setTimeout" call on the functions, but I am overcompensating and forcing users to wait longer without a need if the Callback stuff would work.
Any suggestions? Below is the code:
function runSearchInOrder(callback) {
getDistanceWithLatLong(function() {
updateDB(function() {
printList(callback);
});
});
}
To accomplish this, you need to pass the next callback into each function.
function printList(callback) {
// do your printList work
console.log('printList is done');
callback();
}
function updateDB(callback) {
// do your updateDB work
console.log('updateDB is done');
callback()
}
function getDistanceWithLatLong(callback) {
// do your getDistanceWithLatLong work
console.log('getDistanceWithLatLong is done');
callback();
}
function runSearchInOrder(callback) {
getDistanceWithLatLong(function() {
updateDB(function() {
printList(callback);
});
});
}
runSearchInOrder(function(){console.log('finished')});
This code outputs:
getDistanceWithLatLong is done
updateDB is done
printList is done
finished
wouldn't this work:
function callback(f1, f2) {
f1();
f2();
}
As for passing arguments, be creative.
function1 = (callback1, callback2, callback3) => {
setTimeout(() => {
console.log("function 1 timed out!");
callback1(callback2, callback3);
}, 1500);
}
function2 = (callback1, callback2) => {
setTimeout(() => {
console.log("function 2 timed out!");
callback1(callback2);
}, 1500);
}
function3 = (callback1) => {
setTimeout(() => {
console.log("function 3 timed out!")
callback1()
}, 1500);
}
function4 = () => {
setTimeout(() => {
console.log("function 4 timed out!")
}, 1500);
}
function1(function2, function3, function4);
Just pass down the callbacks from the first function and execute each one, passing down the rest.
OUTPUT
function 1 timed out!
function 2 timed out!
function 3 timed out!
function 4 timed out!
In JavaScript, everything is an object, including functions. That is why you are able to pass callbacks as parameters - you are passing a function as if it were any other object.
In each function declaration, you need to run the callback.
function runSearchInOrder(callback) {
...
callback();
}
function getDistanceWithLatLong(callback) {
...
callback();
}
function updateDB(callback) {
...
callback();
}
Then your code posted above should work.
Related
Recently, I've tried to understand callback functions in JavaScript, however, this concept is still far away from my understanding. I have code like this:
function exampleFunc(callback) {
console.log("Starting...");
setTimeout(() => {
console.log("Logged after 3 secs.");
}, 3000);
callback();
}
function displayMessage() {
console.log("Log it!");
}
exampleFunc(() =>
{
console.log("Further code.");
});
displayMessage();
I've expected that after calling exampleFunc(), program will wait 3 seconds, and then call the callback and rest of code. But instead, the sequence of code is:
Starting...
Further code.
Log it!
Logged after 3 secs.
Why does it happen? I've expected that program will output "Starting", then wait and log "Logged after 3 secs.", then go to callback and output "Further code", and in the end, "Log it!".
Calling a setTimeout does not cause further execution of the code in that function to delay. setTimeout schedules a timeout, then continues executing the rest of the code in the function immediately.
You need to call callback inside the setTimeout callback, so that it runs only after the 3 seconds are up.
You also need to put the call of displayMessage inside the callback passed to exampleFunc.
function exampleFunc(callback) {
console.log("Starting...");
setTimeout(() => {
console.log("Logged after 3 secs.");
callback();
}, 3000);
}
function displayMessage() {
console.log("Log it!");
}
exampleFunc(() => {
console.log("Further code.");
displayMessage();
});
I'm a noob in coding. I'm really sorry about that. I have this code here....
function fn1(){
setTimeout(function(){console.log("fn1")},3000)
}
function fn2(){
console.log("fn2")
}
function fn3(callback, callback2){
if(callback){
console.log("It works!")
} else {
callback2
}
}
fn3(fn1(),fn2())
The objective here is to call Function3(fn3) console.log ("It works") only after Function1(fn1) runs ok. If Function1 fails, it should return Function2.
The output that I'm getting is:
fn2
fn1
I know it is extremely wrong but I don't know WHAT is wrong.
I know that there are other stuff (that I still don't know - like promises, async, await and stuff) but I wanna learn this method first.
Could you guys help me?
Yes, you are right. This is a huge nonsense.
Correct me if I'm wrong: you want the console to log "It works!" after the timeout set in the fn1. Then you'll need the fn1 to tell somehow that it finished it's execution so it can run the console.log. If you want to use the callback approach, then the fn1 could be something like:
function fn1(callback, errorCallback) {
setTimeout(function() {
try {
callback();
} catch (error) {
errorCallback();
}
}, 3000);
}
And the fn3 could go like this:
function fn3() {
fn1(function() { console.log('It works!'); }, fn2);
}
You can call fn3 just with fn3().
To be honest, as simple as these functions are, there's no way the fn2 is called as there are no errors in the code and no human interaction. Well, maybe if there's no standard output available to do the console.log, but I don't know if that's even possible.
As you can see, in the fn3 we are passing two functions as parameters to fn1. The first is an anonymous function that shows the text in the output. The second function is the fn2, that should be run in case of error. No parenthesis here when passing them as parameters as we want to pass functions, not the result of calling them (which would be undefined in this example).
The fn1 receives those functions as parameters and runs them in different situations. The first, when the timeout has finished, and the second if there's any error when calling the callback.
You have to pass references on the functions as parameters of fn3 (you currently call them and pass their result).
Also, in the fn3, you need to call the function.
Your code fixed below (if I correctly understood what you were looking for):
function fn1(next) {
setTimeout(next, 3000);
}
function fn2() {
console.log("fn2")
}
function fn3(callback, callback2){
function itWorks() {
console.log('it works!');
}
try {
callback(itWorks);
}
catch (e) {
callback2();
}
}
fn3(fn1, fn2); // Will display "it works!" after 3 seconds
fn3(undefined, fn2); // Will display "fn2" because trying to call an undefined function
I understood that you want to call f3 after the f1 is called successfully and call the f2 when f1 fails? If yes then see this
function fn3(){
console.log("It Works!");
}
function fn2(){
console.log("fn2");
}
function fn1(){
const promisePass = new Promise((resolve, reject) => {
setTimeout(resolve, 100)}); //Emulate success
const promiseFail = new Promise((resolve, reject) => {
setTimeout(reject, 100);});//Emulate fail
promisePass.then(function(){
fn3();
}).catch(function(){
fn2();
});
promiseFail.then(function(){
fn3();
}).catch(function(){
fn2();
});
}
fn1(); //<<-- calling f1 now will pass and fail the setTimeout method and then
// fn2 and fn3 are called accordingly
I'm trying to make this work, what am I doing wrong?
I want to be able to do some stuff when function one is completed.
function one() {
// do stuff
}
function main() {
//script
//script
one(function() {
// do some stuff when "one" is completed
console.log("one is completed");
});
}
Why this doest fire a callback? (no log entry in the console)
You need to pass the callback as an argument and call it like normal function
function one(a, b, fn) {
// do staff
if (fn) {
fn()
}
}
function main() {
//script
//script
one(5, 6, function() {
// do some stuff when "one" is completed
console.log("one is completed");
}
}
Cause one does not expect a callback, therefore it will be ignored and never called back.
function one(callback) { // <- take a callback
callback(); // <- call back the callback "callback"
}
You need to pass the callback function inside the one() function. Then you need to call that function:
const one = (cb) => {
console.log('in one()');
cb();
}
const main = () => {
one(() => {
console.log('one() is completed');
});
}
main();
OUTPUT:
in one()
one() is completed
function make(callback) {
//some other manipulation to get data to pass it into $.post()
$.post(data, function(response) {
// do something
callback()
});
}
function two() {
make(function() {
console.log('hello');
});
}
console.log('hello') will still trigger first although I used callback. How to make make() run till everything is finished then trigger console.log('hello')?
Your code should work as soon as you call two().
This might visualize your situation better:
function requestSomething(callback) {
$.post(data, function(response) {
// do something
callback();
});
}
function callBackFunction() {
console.log('done!');
}
// Pass callBackFunction, which gets called after request.
requestSomething(callBackFunction);
Is it possible to pass a callback function that does not exist yet? My goal is to have a common function that will wait for another callback function to exist, when it does exist, it should execute it. This is what I have so far, but I can't figure out how to pass the function in that doesn't exist as a function yet.
function RunTemplateFunction(callback, userInfo) {
if ($.isFunction(callback)) {
callback(userInfo);
} else {
var myInterval = setInterval(function () {
if ($.isFunction(callback)) {
clearInterval(myInterval);
callback(userInfo);
}
}, 200);
}
}
I run the function like this:
RunTemplateFunction(MyFunctionToRun, GetUserInfo());
I get MyFunctionToRun is undefined for obvious reasons, I also tried the workaround of passing the function as a string and then convert the string to a function using eval(). But that throws the same error. I also thought of using the new function(), but that actually creates a new function.
Any help is appreciated. thank you.
If you call RunTemplateFunction by undefined there is no way we can see, is callback is defined or not, as we don't have reference to anything.
If you can modify the declaration to accept object as below, we can achieve what we want
function RunTemplateFunction(options, userInfo) {
if ($.isFunction(options.callback)) {
console.log('called1',userInfo);
options.callback(userInfo);
} else {
var myInterval = setInterval(function () {
if ($.isFunction(options.callback)) {
console.log('Called dynamically!!');
clearInterval(myInterval);
options.callback(userInfo);
}
}, 200);
}
}
var options = {}
RunTemplateFunction(options,{user:122});
options.callback = function(){
console.log("I'm called!!");
}
This will print
Called dynamically!!
I'm called!!
EDIT:
We can also call callback function in following way without setInterval, it will look different but options.callback variable is replaced by template.callMe function and its instantaneous also.
function TemplateRunner(userInfo){
this.callMe = function(cb){
this.templateFunction(cb);
}
this.templateFunction = function(callback){
callback(userInfo);
}
}
var template = new TemplateRunner({user:100})
template.callMe(function(user){
console.log('call me1',user);
});
template.callMe(function(user){
console.log('call me2',user);
})
This will print
call me1 {user: 100}
call me2 {user: 100}