How do you properly return multiple values from a promise?

Der Hochstapler picture Der Hochstapler · Feb 24, 2015 · Viewed 107.6k times · Source

I've recently run into a certain situation a couple of times, which I didn't know how to solve properly. Assume the following code:

somethingAsync()
  .then( afterSomething )
  .then( afterSomethingElse )

function afterSomething( amazingData ) {
  return processAsync( amazingData );
}
function afterSomethingElse( processedData ) {
}

Now a situation might arise where I would want to have access to amazingData in afterSomethingElse.

One obvious solution would be to return an array or a hash from afterSomething, because, well, you can only return one value from a function. But I'm wondering if there is way to have afterSomethingElse accept 2 parameters and invoke it likewise, as that seems a lot easier to document and understand.

I'm only wondering about this possibility since there is Q.spread, which does something similar to what I want.

Answer

Benjamin Gruenbaum picture Benjamin Gruenbaum · Feb 24, 2015

You can't resolve a promise with multiple properties just like you can't return multiple values from a function. A promise conceptually represents a value over time so while you can represent composite values you can't put multiple values in a promise.

A promise inherently resolves with a single value - this is part of how Q works, how the Promises/A+ spec works and how the abstraction works.

The closest you can get is use Q.spread and return arrays or use ES6 destructuring if it's supported or you're willing to use a transpilation tool like BabelJS.

As for passing context down a promise chain please refer to Bergi's excellent canonical on that.