Skip to content Skip to sidebar Skip to footer

Understanding Javascript Callbacks And Formal Parameters

Here is an example of a question that I am slightly confused about. Function one calls function two, and passes it a callback that has a formal parameter. My answer: function one

Solution 1:

anatomy first

JavaScript can be confusing because there's a variety of ways to express functions – for all intents and purposes, the functions below can be considered identical

// named functionfunctionmyfunc (param1, param2) {
  return returnValue
}

// function literal syntaxconst myfunc = function (param1, param2) {
  return returnValue
}

// arrow function with explicit return (note { ... })constmyfunc = (param1, param2) => {
  return returnValue
}

// arrow function with implicit returnconstmyfunc = (param1, param2) => returnValue

Above you can see functions have parameters – below, you'll see function calls have arguments

// call myfunc with 0 arguments
myfunc ()

// call myfunc with 1 argument
myfunc (arg1)

// call myfunc with 2 arguments
myfunc (arg1, arg2)

they're just functions

a) Which function calls the callback function?

So wherever we see a function supplied with arguments, we know we're dealing with a call – to answer A, just look to see the enclosing function of the call

functionsomeFunc (param1, param2) {
  // do somethingconst result = param1 * 2// param2 called with result
  param2 (result)
}

Hey look, param2 (result) is a function call. We look to the enclosing function to see that someFunc is the one that called it

b) Which function supplies the actual parameter of the callback function?

Well that sounds silly doesn't it? That's like asking "Who does Bobby's name belong to?" Bobby, of course. You probably meant to ask, which function supplies the argument – in which case, that answer would be someFunc – it supplies result argument

c) Why give a callback function parameters?

This is instantly answered as soon as we stop calling functions a "callback" – a callback is a function, not the other way around. We give functions parameters so that we can affect the behaviour of the function

d) What are you giving up when you have an 'asynchronous' call without supplying a callback function?

Don't worry about asynchronous vs synchronous function calls; there's just function calls. Function calls happen at different times, but at some point the call will evaluate the function's body with the supplied arguments and return the result; undefined or otherwise

In most cases, you "give up" the ability to do anything useful with the result – look at our function again: if we don't supply param2, result just goes unused

functionsomeFunc (param1, param2) {
  // do somethingconst result = param1 * 2// param2 called with result
  param2 (result)
}

But of course that's not always true. To understand why, we have to first fix your question tho

d) What are you giving up when you have a call without supplying an argument?

Kind of a silly question right? But it's no different for callbacks functions – they're just ordinary values like anything else

Below we have someFunc with a function parameter naïvely named callbacksomeFunc produces a "valid" result with or without the callback specified – so the answer for D is: you give up nothing, explicitly

functionsomeFunc (x, callback) {
  if (callback)
    return callback (x * 10)
  elsereturn x * 2
}

// with the callback
someFunc (5, console.log) // 50// withoutconsole.log (someFunc (5)) // 10

e) Can the called function in an asynchronous call ever contain synchronous calls?

Yes, functions can call other functions. This idea of "sync" and "async" in javascript is historically a mental construct and therefore a lot of people have differing opinions on it. To add to this, newer versions of JS have an async keyword which will implicitly convert your function's return value to a Promise

To further illustrate this, observe doSomething – is it "asynchronous" or is it "synchronous" ?

// "synchronous" functionconstmult = (x,y) => x * y

// "synchronous" functionconstdouble = (x) => mult (x, 2)
  
// function with "callback"constdoSomething = (x, callback) =>
  callback (x)

// is it async ?
doSomething (5, x => {
  const result = double (x)
  console.log (result) // 10
})

// or is it sync ?console.log (doSomething (5, double)) // 10

where to go from here

There is actually a more uniform understanding of asynchrony in JavaScript now – especially with the standardization and widespread adoption of Promises. ES2017 adds new control syntax async/await too. "Callback" patterns are mostly dead – even the dominant force that was Node with it's popular "Node-style (error first) callbacks" has conceded to support Promised-based interfaces for asynchronous programs

That's not to say higher-order functions (functions with function parameters, or functions that return other functions) are without their uses – you'll see the functional programmers waving their Array.prototype.map and Array.prototype.reduce all over the place

But this idea of "callbacks" can be extremely powerful – especially when represented in ways other than we've seen above. Continuation-passing style is a style where we pass a continuation (another fancy name for a function) that serves as the "next" step of our program. I've written a lot on the subject of continuations. If you find this stuff interesting, keep reading. You'll learn amazing things about the call stack, principles of recursion, functors, monads, all sorts of things !

constcont = x => k => k (x)

constdouble = x => cont (x * 2)

consttriple = x => cont (x * 3)

double (2) (console.log)                            // 4
double (2) (double) (console.log)                   // 8
double (2) (double) (double) (console.log)          // 16
double (2) (double) (double) (double) (console.log) // 32
double (2) (triple) (console.log)                   // 12

Post a Comment for "Understanding Javascript Callbacks And Formal Parameters"