Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jldailey
Last active December 20, 2015 02:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jldailey/6054563 to your computer and use it in GitHub Desktop.
Save jldailey/6054563 to your computer and use it in GitHub Desktop.
A draft blog post about Promises

Promises

The Promise API's true value lies in lifting control out of the compiler's hands, and into the hands of our runtime, using a very simple structure. Rather than the syntax of the source code being the only description of the relationship between pieces of code (e.g. a callback pyramid), now we have a simple API for storing and using those relationships.

TL;DR The core API of a Promise object should be:

.wait(cb)       # cb gets (err, result)
.finish(result) # cb will get (undefined, result)
.fail(err)      # cb will get (err, undefined)

In the public Promises API .then() establishes such a relationship, but fails in a number of ways for me. The word 'then' is given a second meaning, already being used in "if this then that". If not literally in your language (CoffeeScript), then in your internal dialogue when you are reading and writing conditional expressions of all kinds, such as this sentence.

I find that people who are new to Promises take a long time to 'boot up' to seeing how valuable they are, and the abstractness of then is part of the problem.

What is the core service that the API should provide? To cause some code to wait for other code to either finish or fail.

I suggest that wait is the most accurate verb for the action here, and communicates immediately why I would want to use promises... because I need some code to wait for the promise to deliver.

Using then values the lyricism of the resulting code over it's actual clarity, making it just a bit too clever.

Extensions to the API:

"I promise to touch all the files" is an example of a hard promise to make currently, when each touch is asynchronous, since you don't know which file is the last, or when they are all complete. What you need are incremental promises.

promise.progress(current, [maximum]) # emits 'progress' events
promise.finish(delta)                # calls .progress(current+delta)

"I promise to recurse over all directories", is extra hard because you don't even know the size of the goal at the start, and must update that knowledge recursively.

# only finish() promise after b has finished
promise.include(promise_b)

This allows the creation of promises that are both recursive and incremental, which lets you create a tree of promises inside any workload, without leaking knowledge to (or requiring it of) the waiting code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment