Callback functions

I am having trouble understanding what the difference is (if any) between the below two sets of code.

function asyncDouble(num, callback) {
    setTimeout(() => callback(num * 2), 1000);
}
asyncDouble(10, (x) => console.log(x));
// (after one second) logs `20`
function asyncDouble(num, callback) {
    setTimeout(callback(num * 2), 1000)
}
asyncDouble(10, (x) => console.log(x));
// (after one second) logs `20`

They both work and return the correct result, but I am wondering if this means we do not have to write the entire function as the first argument to setTimeout? Just confused as to why it also works in the second example.

Those don’t do exactly the same thing, it’s a matter of timing. For example, for the first:

function asyncDouble(num, callback) {
    console.log('apple')
    setTimeout(() => callback(num * 2), 1000);
    console.log('beta')
}
asyncDouble(10, (x) => console.log(x));
// apple
// beta
// 20

and the second one doesn’t work the way we want:

function asyncDouble(num, callback) {
  console.log('apple')
  setTimeout(callback(num * 2), 1000)
  console.log('beta')
}
asyncDouble(10, (x) => console.log(x));

// apple
// 20
// beta

The first one waits a second for the “20” output and the second one doesn’t. Change the delay to 5000 to see the difference.

Why doesn’t the second one work? Because callback(num * 2) gets evaluated immediately and substitutes the return value of that code into setTimeout. Since console.log doesn’t return anything, you are calling setTimeout(undefined, 1000) - so, the console.log gets evaluated immediately and then after the delay, “nothing” happens.

But in the first example, we aren’t invoking the callback, but are wrapping it in an arrow function (a very common pattern). So setTimeout is being passed a function that gets evaluated after the delay.

But yeah, this is confusing.

1 Like

I see, so it’s almost as if callback(num * 2) in the second example is working independent of the setTimeout method, and then the setTimeout happens at the end. Thanks, that’s cleared a lot up for me! :slight_smile:

I think it would be more accurate to say that the callback(num * 2) is getting called when the setTimeout is being set up. But we want it to be called after the timeout.

1 Like