Promises, Promises Pt. 1
The Art of Waiting Around
It has been said of history that it’s “just one damned thing after another.” (By the way, that’s the title of a fantastic book about time travel by Jodi Taylor, and I can’t recommend it enough). The way we tell the story of history is often very sequential. An archduke is shot in Sarajevo, the Central Powers start a war, yada, yada, yada. But this telling hides a very complicated web of events that encapsulates trade agreements, royal marriages, personal affronts, and a regressive genetic defect called the “Hapsburg Jaw”.
In web development, as well as history, we deal with a rather complicated set of systems that are talking to each other. Web servers, databases, APIs, web workers, calls to local storage, animations, and that blasted user who keeps pushing buttons. A lot of software assumes that someone will request a task and the rest of the world will just wait till that task is done, and change nothing in meantime. There may be contexts where that occurs, but web dev isn’t one of them.
The Epic Tale of Chips & Cheese
Now, this isn’t an entirely healthy approach. For however long your roommate is gone, you just keep staring at the door waiting for him to come back. Wouldn’t you rather be doing stuff? Listening to music? Practicing dance moves? I mean, live your life! Let’s create a function called
sendRoommateFor() and attach an
onReturn event listener that does something with
Well, that’s better. You were able to break this into two distinct processes: 1) you sent your roommate for chips and shredded cheese, and then 2) when he came back, you started another process that made and ate the nachos. In the meantime, you were free to do whatever your heart desired, which may or may not have involved dancing around in the kitchen to Taylor Swift.
And now, Promises
Now, this doesn’t seem like much of an improvement over the last, but there are a lot of great combinations we can do here. Let’s say that you’re making nachos for your significant other, who is sitting in the TV room. She has asked for nachos, but she doesn’t need to know about this whole roommate drama. She’s not even concerned with how long it’s taking: she can wait forever for these nachos, but she wants nachos. We can basically hand her a nacho promise, and then she can eat them when they arrive. Now it looks like this:
In a nutshell, that’s the “what” of promises. Promises are asynchronous values that can be produced, transformed, and combined. Because of this, it’s really easy to write different pieces of software that perform different functions on these promises:
|Producer (Roommate)||Generates the content (via http request, timeouts, etc.)|
|Transformer (Me)||Takes a promise and converts the ingredients into something useful|
|Consumer (Significant Other)||Does something with the transformed content, such as updating a view|
One important principle of writing software is the “Single Responsibility Principle”, where each bit of software is responsible for only one job, like interfacing with an API or updating the view. Promises let us do that with ease, and if the behavior of one of those pieces changes, for instance, if an application is depending on an API to behave a certain way and its signature changes, then we can write different transformers to let it meet the consumer’s specifications instead of expecting the consumer to change.
Now that we’ve learned the “what”, we’re ready to learn the “how”. We’re going to spend the next post creating and combining promises, and after that, we’re going to step through a few real-life examples.