First: A promise1
Promises are one thing that’s new in ES6. They encode, in a neat little state machine, how an asynchronous action might progress. From the mozilla docs:
A Promise is in one of these states:
- pending: initial state, not fulfilled or rejected.
- fulfilled: meaning that the operation completed successfully.
- rejected: meaning that the operation failed.
A short example of using the (equally
(and the equally, equally
arrow function syntax)
for accessing HTTP content:
window.fetch('https://boinkor.net/index.xml'). then((response) => response.text()). then((txt) => console.log(txt.split("\n")));
Which would make an HTTP request to this blog’s Atom feed, returning a promise; then when that promise resolves with a response, we request the response body, which returns a promise in turn. When the second promise resolves, we print the first line of the body.
At first glance, this is much easier to follow than the callback hell we all had to deal with before. But wait - there’s more!
As you’d expect from a properly asynchronous tool, you can
promises even if they’re resolved. (Because things might happen faster
or slower than your computer can execute the next JS statement, of
And that brings us to the neat thing that I saw for the first time yesterday.
I was pair-programming with somebody yesterday, and we were musing
about chaining HTTP requests. We’d written a thing that was firing off
all sorts of requests using
fetch simultaneously, and waited for
them all to resolve
we wanted to fire the requests off one after the other.
So, without blinking, my pair writes this code:
urls.reduce( (p, url) => p.then(() => fetch(url).then(handleResponse)), Promise.resolve());
What. Uh. This does the right thing, but huh? A bunch of insights have let do this short piece of code:
Promise.resolve()returns a promise that is already in the resolved state. But as mentioned before, it can have
.thencalled on itself3. And so will every promise returned by
.thenin turn returns a promise, which lets us chain them together.
.reducewill run a function across an array’s contents and the previous function’s return value.
And so, using the resolved promise as a zero element, this piece of code gathers up requests, one after the other.
I made a promise, but allow me to drift off into maths appreciation
briefly: Promises, combined with some algebra (and operators like
reduce that take advantage of the algebraic nature of stuff) allow
you to express realistically cool things in a tidy way.
I’d encourage you to go forage in the mozilla docs for more ES6
fetch alone is worth a lot)! Look
But more importantly, think about what you could build if you had a sensible and well-integrated state machine abstraction for your most complex software task.