Personal computing discussed

Moderators: SecretSquirrel, just brew it!

 
Crayon Shin Chan
Minister of Gerbil Affairs
Topic Author
Posts: 2299
Joined: Fri Sep 06, 2002 11:14 am
Location: Malaysia
Contact:

How to use callbacks?

Wed Mar 23, 2016 5:59 am

I'm starting out in Javascript and I quickly ran into the problem of callbacks. Specifically, if I want to write something like this:
function dosomethingcomplicated(){
   a = step1(params, callback(){
      ...
      return result
   })
   step2 does something with a....
   step3...
}

I can't return anything from the callback because then the interpreter has already executed step2 with an undefined 'a'. So I have to move all functionality into this callback, and then if everything's in a callback, then I can't return anything to anything 'higher up' in the program, it's just a bunch of callbacks strung together and the code moves towards the right.

How are things actually done in Javascript? I imagine this is a solved problem.
Mothership: Thuban 1055T@3.7GHz, 12GB DDR3, M5A99X EVO, GTX470+Icy Vision Rev.2@840/3800, Vertex 2E 60GB
Supply ship: Sargas@2.8GHz, 12GB DDR3, M4A88TD-V EVO/USB3
Corsair: Macbook Air Ivy Bridge
 
just brew it!
Gold subscriber
Administrator
Posts: 49711
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Re: How to use callbacks?

Wed Mar 23, 2016 6:20 am

Callbacks (in any language, not just JavaScript) are typically used when you're dealing with an asynchronous event that you DON'T want to wait on. The fact that you're encountering this issue in the first place may be an indication that you need to re-think your overall approach to whatever it is you're trying to do.

Care to provide any specifics?
Nostalgia isn't what it used to be.
 
meerkt
Gerbil Elite
Posts: 809
Joined: Sun Aug 25, 2013 2:55 am

Re: How to use callbacks?

Wed Mar 23, 2016 9:20 am

Not sure what you're trying to do, but read up on Javascript closures.
 
Crayon Shin Chan
Minister of Gerbil Affairs
Topic Author
Posts: 2299
Joined: Fri Sep 06, 2002 11:14 am
Location: Malaysia
Contact:

Re: How to use callbacks?

Wed Mar 23, 2016 11:08 am

just brew it! wrote:
Callbacks (in any language, not just JavaScript) are typically used when you're dealing with an asynchronous event that you DON'T want to wait on. The fact that you're encountering this issue in the first place may be an indication that you need to re-think your overall approach to whatever it is you're trying to do.

Care to provide any specifics?

I don't have any specific code, it's just something I realized when I was working on someone else's code. And I asked around and nobody seemed to understand what I was talking about so I couldn't work on anymore code because I didn't understand callbacks.

You're right, if step2 and step3 really depend on step1 to run, then step1 shouldn't use a callback, which will be like a totally different codepath branching off the main program flow. Thanks!
Mothership: Thuban 1055T@3.7GHz, 12GB DDR3, M5A99X EVO, GTX470+Icy Vision Rev.2@840/3800, Vertex 2E 60GB
Supply ship: Sargas@2.8GHz, 12GB DDR3, M4A88TD-V EVO/USB3
Corsair: Macbook Air Ivy Bridge
 
morphine
Gold subscriber
Gerbilus Supremus
Posts: 11406
Joined: Fri Dec 27, 2002 8:51 pm
Location: Portugal (that's next to Spain)

Re: How to use callbacks?

Wed Mar 23, 2016 11:12 am

As others have pointed out, it's a structural thing.

However, the last post in this Stack Overflow thread details something which may be useful to you sometime in the future, if you're building something complicated - JQuery Promises.
There is a fixed amount of intelligence on the planet, and the population keeps growing :(
 
Duct Tape Dude
Gold subscriber
Gerbil Elite
Posts: 585
Joined: Thu May 02, 2013 12:37 pm

Re: How to use callbacks?

Wed Mar 23, 2016 11:41 am

Unfortunately the best way to solve this is to learn! I'd start with...

1) How closures work http://stackoverflow.com/questions/1111 ... sures-work
Basically, you can reference variables in a function's scope or any parent scope.

2) How asynchronous calls work http://stackoverflow.com/questions/1422 ... 3#14220323
Basically, do not "return" a value when using async calls. Instead, pass it to another function which is dubbed a callback. Life does not pause for async calls.

2a) AFTER you understand what an async call is, then you can benefit from an async library like https://github.com/caolan/async
2b) If you are feeling daring and have an idea of the above you can benefit from promise library instead like https://github.com/petkaantonov/bluebird/
These libraries are not necessary to learn and use Javascript but really help for lots of nested async calls.

And keep in mind that functions are first-class citizens in JS, which means you can pass them around like variables, or assign variables to functions. For example:

var a = function someFunction (param) {
    console.log(param);
}
a("Hello!");     // Outputs "Hello!"

function b(param) {
    console.log(param);
}
b("Hello!!");    // Outputs "Hello!!"

var c = console.log;
c("Hello!!!");   // Outputs "Hello!!!"

// You can even declare a function, wrap it in parentheses, and run it with some parameters.
// Because it's a closure, it can still see other functions outside it.
(function(param) { c(param); })("Hello!!!!");  // Outputs "Hello!!!!"

// This doesn't work because someFunction was part of a's declaration
someFunction("Hello!"); // ReferenceError: someFunction is not defined


A solution to your code could be something like
function step1(params, callback) {
    var result1 = "Step 1 has these params" + JSON.stringify(params);
    callback(result1);
}

function step2(params, callback) {
    var result2 = "Step 2 params = " + JSON.stringify(params);
    callback(result2);
}

// Do something complicated
var startingParams = { hello: "there" };
step1(startingParams, function(step1Result) {
    console.log("Step 1's result is: " + step1Result);
    step2(step1Result, function(step2Result) {
        console.log("Step 2's result is: " + step2Result);
    })
});

// Output:
// Step 1's result is: Step 1 has these params{"hello":"there"}
// Step 2's result is: Step 2 params = "Step 1 has these params{\"hello\":\"there\"}"


Edited for formatting
Last edited by Duct Tape Dude on Wed Mar 23, 2016 2:17 pm, edited 2 times in total.
 
morphine
Gold subscriber
Gerbilus Supremus
Posts: 11406
Joined: Fri Dec 27, 2002 8:51 pm
Location: Portugal (that's next to Spain)

Re: How to use callbacks?

Wed Mar 23, 2016 11:45 am

A very simple solution to this is having step1 not return before it's done, er, calling the callback.
There is a fixed amount of intelligence on the planet, and the population keeps growing :(

Who is online

Users browsing this forum: No registered users and 1 guest