For someone coming from a strong background in Ruby, transitioning to JavaScript was not without hardship. In particular, the callback-centric, highly asynchronous style had me pining for the ability to block. The new-ish Promise pattern improves the situation, but it still has a learning curve. After working with it, specifically the great Bluebird promise library, I can tell you it’s not as complicated as it sounds.

Most of the functions in the Promise interface fall into little groups, arranged along a few small dimensions. Those dimensions are:

  1. Type of value contained in the promise (scalar, array, or object), or of its properties (function or not).
  2. Side effects like mutation vs. pure functions
  3. Success callback vs. error callback

This would be fun to graph, but in English:

  • then calls the given function with the value of the promise as its first argument (unless the promise has already been rejected).

  • map is like then for arrays. It applies the given function to every item in the array, and returns a new array with the function’s return value for that item, in the same order.

  • each is like map: side effects for arrays. The original array is returned (plus any mutation you may have applied to its members).

  • tap is like then: side effects for scalar values.

  • catch is like then but for promises that have been rejected (which means some earlier step in the promise chain raised an error).

  • tapCatch is a combination of catch (operate on rejected promises) and tap (for side effect).

  • get takes a string (or number in the case of arrays) and returns the promise’s value’s property with that name.

  • call is like get, but for properties that are functions. You can also pass arguments to the called function.

  • all is for when the value of the promise is an array containing more promises. It returns only once all of those promises have resolved.

  • props is all for when the value of the promise is an object (or Map), and its properties are promises.