Given a named function utilized to handle a Promise
value
function handlePromise(data) {
// do stuff with `data`
return data
}
a) Passing the named function handlePromise
as a reference to .then()
promise.then(handlePromise)
b) Using an anonymous or named function as parameter to .then()
and returning the named function handlePromise
with Promise
value as parameter within the body of the anonymous or named function passed to .then()
promise.then(function /*[functionName]*/(data) {return handlePromise(data)})
Questions
Are there any differences between patterns a) and b)?
If the answer to 1. is yes, what are the differences that should be considered when using either pattern?
From a logic perspective there is not anything that would set them apart.
From a source code and style perspective my personal taste is against inline function declarations as they are harder to read (when reading someone else's code, when reading my own its a work of art LOL)
From a debugging perspective when the nesting gets deep its is harder to debug when you have a long stack trace of anonymous calls.
From a performance perspective it is browser dependent. With no significant difference using Firefox. Using Chrome Canary 60 and all versions before. Inline anonymous function declarations are significantly slower after the first call than defined function statements, and function expressions. This is true for both traditional and arrow functions.
Comparing the two alternatives and timing the while loop only
var i,j;
const f = a => a;
j = i = 10000;
while(i--) f(i); // timed loop
while(j--) (a=>a)(j); // timed loop
The pre defined function is executed 870% quicker than the inline function.
But I have yet to see anyone use promises in performance critical code, the difference in time on the test machine (win10 32bit) is 0.0018µs(*) for f(i)
and 0.0157µs for (a=>a)(i)
(*) µs denotes microseconds 1/1,000,000th of a second
The differences are small to insignificant, more a matter of personal taste and style than anything else. If you work in a team use the style outlined in their style guide, if you are project lead or work on your own, use what you are most comfortable with.
The edge case as shown in BenjaminGruenbaum answer I do not consider valid as he explicitly calls f() in then(()=>f())
without an argument. That is the same as const ff = () => f(); delay(0).then(ff)
and not a quirk of how the function is defined.
It is possible to create a case where there is a difference when no argument is passed, but it is a stretch and generally you should pass f
and not function(x) { return f(x); }
or x => f(x)
because it is cleaner.
Here is an example causing a difference, the rationale is that functions that takes parameters can cause side effects with those parameters:
function f() {
if(arguments.length === 0) console.log("win");
else console.log("Hello World");
}
const delay = ms => new Promise(r => setTimeout(r, ms)); // just a delay
delay(500).then(f); // logs "Hello World";
delay(500).then(() => f()) // logs "win"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With