A Deep-Dive into ES6 Promises
Promises are an awesome way to manage asynchronous code in both client and server-side Javascript. And now that native promises have landed in ES6, it’s a great time to get started if you haven’t used them before. That said, once you get beyond the basic concepts, it not always obvious what their full potential is.
In this talk we’ll dive deep into using ES6 promises. We’ll see how promise chaining and composition makes it easy to manage complex sequences of asynchronous operations. We’ll learn how to correctly handle exceptions with promises. Finally, we’ll talk about strategies for unit testing code that uses promises.
You’ll leave this presentation understanding how you can fully leverage ES6 promises to write asynchronous code that is easier to comprehend and reason about. Promises are here to stay, and once you’ve seen the light, you won’t want to go back.
Why promises? What problem are we trying to solve here? JS is fundamentally asynchronous; and async is hard to do well.
Quick overview…
What’s a promise? The formal definitions are very dry and not always easy to understand. A good way to understand is to compare code with/without promises. Compare ye olde jQuery ajax vs the newer fetch API (fetch/then/catch example)… not hugely different.
But then you get into nested ajax calls… and you quickly get into Callback Hell(tm) aka the callback pyramid of doom. Nesting a fetch call is cleaner – (fetch/then with return fetch/then/catch).
Browser support? Latest browsers have them; and there are polyfills, transpilers and frameworks. Commonly people do use them in Node as well.
Deeper dive…
Chaining… then() and catch()
Composition… then and catch only take functions. They can return a promise; return an exception; or return a value.
Throw an exception… so long as you return correctly, you can pass meaningful errors.
Note that when you start getting something that looks a like the pyramid of doom, you can use Promises.all to simplify the code.
A side effect is you can clearly document things in terms of inputs and outputs, and be really clear on the conditions that will affect it.
Unit Testing… because we are focusing on inputs and outputs, testing can be pretty clean. You can dummy up a response easily by using Promise.resolve(), which creates an immediately-resolving promise.
Promises are awesome!
- chainable & composable
- resinstate input/output semantics
- testable & documentable
They are definitely here to stay, it’s definitely time to get across them!