Let's say you have a Promise, you do some stuff with it then just log back when all processing is finished:
const promise = new Promise((res,rej) => setTimeout(res('Resolved'), 2000))
promise
.then(result => console.log(result))
.then(console.log('Success!'))
.catch(console.log('Error!'))
What's wrong with that code? Well, here's the log:
// Success!
// Error!
// Resolved
That is nothing like expected. What happened?
In fact, both then
and catch
expect functions as arguments. Those console.log()
s are just statements, not functions, thus they're immediately evaluated.
The simplest solution is to turn those statements into anonymous functions:
promise
.then(result => console.log(result))
.then(() => console.log('Success!'))
.catch((err) => console.log('Error!'))
// Resolved
// Success!
Keep in mind this is not a quirk of Promises per se, but the language in general. Other functions that take callbacks are also prone to the same mistake:
setTimeout(console.log('Timed out'), 10000)
// 'Timed out' is printed immediately
// Some environments would throw TypeError [ERR_INVALID_CALLBACK]: Callback must be a function
setTimeout(() => console.log('Timed out'), 10000)
// 'Timed out' is printed after 10 seconds
As someone who's learning JS when Promises are the norm, it seems I've sort of skipped this basic lesson on callbacks.
Top comments (2)
Another thing you can do, when the
then
statement takes only one function with the return of the promise as its only parameter, is to just write its name, something like this:Yeah I usually do that as well, and in a sense that may have led me to believe
then(console.log('smth'))
would be okay. Subtle but makes all the difference.