An overview of JS promises for all skill levels. Starts with an excellent analogy of thread-blocking as sneezing:
You don't want to write code that's sneezy.
You can effectively think of promises as stripped-down event listeners. They wait for a specific thing to happen, then they trigger a response, whilst recording either a success or failure state. That makes them particularly useful for asynchronous functionality:
This is extremely useful for async success/failure, because you're less interested in the exact time something became available, and more interested in reacting to the outcome.
As a result, promises can have four states: fulfilled (yay!), rejected (failure...), pending (waiting around for the trigger), or settled (no longer pending). There's also thenable but... what?!
Because of these states, you can use promises to build sequential logic chains using then()
and catch()
. Jake's got a whole bunch of great code examples which are worth checking over for exact syntax and useful shortcuts. Because promises are effectively set once, they also allow you to reuse initial results. For example, if you fetch an array of URLs from an API using a promise, you can then keep referring back to the output of that promise to loop through the array and fetch data from each URL, without consistently re-fetching the original info.
Also useful to know:
Promise rejections skip forward to the next then()
with a rejection callback (or catch()
, since it's equivalent).
One of the hardest concepts when working with async logic is that content order is always unknown. For example, if you're fetching a list of URLs and then want to loop through that list to return article information, you can't just use a for
loop. Loops aren't "async-aware", so they would output the content in whatever arbitrary order the promise had resolved in. Your code wouldn't always return the same result when given the same input – not ideal! Again, Jake has a useful example of how to convert that type of logic into a promise chain.
Better yet, promises give us the ability to make use of multi-thread data fetching within the browser:
Promise.all
takes an array of promises and creates a promise that fulfills
when all of them successfully complete.
That can actually reduce your code length and significantly increase load times. Neat.
Jake also takes a look at how generators in JS can help write async code in a way that reads like synchronous code. Also neat.