DEV Community

Cover image for 10 fun facts about Javascript Promises
The Teabag Coder
The Teabag Coder

Posted on

10 fun facts about Javascript Promises

Promises are always asynchronous

Promise's callback always be executed after synchronous code

const promise = Promise.resolve(); 
promise.then(() => console.log('async')); 
console.log('sync');

//sync
//async
Enter fullscreen mode Exit fullscreen mode

Chained promises return new promises

Promise then returns a new promise each time its invoked

const p = Promise.resolve(); 
const chain = p.then(() => {}); 
console.log(p === chain); //false
Enter fullscreen mode Exit fullscreen mode

Forever then()

Promises support infinite chaining

Promise.resolve(1) 
    .then(value => value + 1) 
    .then(value => value + 1) 
    .then(value => console.log(value)); // 3
Enter fullscreen mode Exit fullscreen mode

You can convert callbacks to promises

You can wrap older code which uses callback in promise to work with modern async/await

function asyncOperation(callback) { 
    setTimeout(() => callback(null, 'Im a callback'), 1000); 
} 

const promisified = () => new Promise((resolve, reject) => { 
    asyncOperation((err, result) => { 
        if (err) reject(err); 
        else resolve(result); 
    }); 
});

promisified().then(result => console.log(result)); // "Im a callback"
Enter fullscreen mode Exit fullscreen mode

Promise.resolve() doesn’t always create a new promise

If you pass a non-Promise value, Promise.resolve() wraps it into a resolved promise. But if you pass a promise, it just returns that same promise.

const p1 = Promise.resolve('Hello'); 
const p2 = Promise.resolve(p1); 
console.log(p1 === p2); // true
Enter fullscreen mode Exit fullscreen mode

You can handle errors anywhere in the chain

Promise.reject('Error!')
  .then(() => console.log('This will not run'))
  .then(() => console.log('This will also not run'))
  .catch(err => console.log('Caught:', err))
  .then(() => console.log('This will run'));
Enter fullscreen mode Exit fullscreen mode

finally() doesn’t pass values

The finally() method doesn't receive or modify resolved values. It’s used for cleaning up resources and runs whether the promise resolves or rejects.

Promise.resolve('resolved')
  .then(value => console.log(value))
  .finally(() => console.log('Cleanup'))

//resolved
//cleanup
Enter fullscreen mode Exit fullscreen mode

Promises are immutable once settled

Once a promise is settled (resolved or rejected), its state is immutable. It can't be changed after that, even if you try to resolve/reject it again.

const p = new Promise((resolve, reject) => {
  resolve('First');
  resolve('Second');
});
p.then(value => console.log(value));  //"First" (only the first value is used)
Enter fullscreen mode Exit fullscreen mode

You can chain catch() to handle specific errors

Promise.reject('type C error')
  .catch(err => {
    if (err === 'type A error') console.log('handle type A');
    throw err;
  })
  .catch(err => {
    if (err === 'type B error') console.log('handle type B');
    throw err;
  })
  .catch(err => {
    if (err === 'type C error') console.log('handle type C');
    throw err;
  })
Enter fullscreen mode Exit fullscreen mode

You can use await with non-promise values

async function demo() {
  const result = await 42; //not a promise
  console.log(result);      
}
demo(); //42
Enter fullscreen mode Exit fullscreen mode

That's it! Thank you for reading this far. Till next time!

Top comments (0)