This pattern is unrelated to promises. It has to do with passing a callback. The principle is the same with, for example, array.forEach
, or with setTimeout
or your own function that can receive a callback.
So for example, if you define such a function yourself, it could be (like you mentioned in comments):
function test(callback) {
callback("test-output");
}
If you want to print "test-output", you would call test
like in this short version:
test(console.log);
You could also call it like in this longer version:
test((value) => console.log(value));
The long version
In the latter case you actually create an anonymous (arrow) function on-the-fly:
(value) => console.log(value)
This is a wrapper around console.log
. If you call it with some argument, you end up calling console.log
with that same argument. You have in some way created a synonym for console.log
because to the outside world it behaves in the same way. You could do something more elaborate, and define that function in a non-anonymous way:
function wrapper(value) {
console.log(value)
}
And then use that -- now named -- function at the place where we had the anonymous function:
test(wrapper);
We didn't change much: we just moved the function to another spot, turned it into a non-arrow function (not really needed), and gave it a name (wrapper
). So the name wrapper
is now synonym for that function. And so passing that to test
is just the same thing as passing the literal function definition itself.
This makes very clear now that we just added a tiny, extra layer on top of the final call to console.log
: first we call test
, then test
will call wrapper
, and finally wrapper
will call console.log
.
The short version
The first, shorter way of calling test
, is not beating around the bush: it just says: "the function I want you to call is console.log
". And so test
calls it:
callback("test-output");
It provides the argument "test-output". Do realise that the callback
variable is a reference to console.log
now, since that is the argument we passed to test
. Both console.log
and callback
now reference the same function. So callback("test-output")
is just the same as console.log("test-output")
.
So here we have one level less than in the longer version. The sequence is that we call test
, and then test
calls console.log
. The wrapper thingie is not there.
NB: There are some things to say about this
binding here, which does not have any bearing on the example above, but if that topic concerns/interests you, then read more about it in: How does the this
keyword work in JavaScript.