Resolving Futures w/multiple values

Hi,

I had a short discussion with Anne van Kesteren on #whatwg about the 
usefulness of allowing multiple values to be passed to the 
FutureResolver's resolve() method (see: 
http://dom.spec.whatwg.org/#futureresolver). We agreed it was worth 
exploring so I'm forwarding the idea on.

This issue came up because I noticed that it can be difficult to wrap 
some existing node.js libraries with a Futures/Promises API. It is a 
fairly common practice in node.js to pass multiple values to callbacks 
when asynchronous operations complete. This behavior is even supported 
by popular code-flow utility libraries (see: 
https://github.com/caolan/async#waterfall). Unfortunately, the current 
Futures API does not easily support wrapping node.js APIs that exhibit 
this behavior because its resolve() and accept() methods only take one 
argument. This distinction can be overcome in some cases by a simple 
wrapper that passes all of the arguments as an array so they represent a 
single value. But there are also cases where this is insufficient:

Consider this node.js async operation:

foo(param1, param2, callback)

When it completes, it calls:

callback(err, bar, baz)

In order to convert this continuation-passing style API to a Future, a 
wrapper creates a new function that wraps the async operation and passes 
a callback that will call reject() if a non-null 'err' parameter is 
defined and resolve() with an array containing both 'bar' and 'baz' 
otherwise. The code to use such a wrapper and its resulting Future might 
look like:

futureFoo = wrap(foo);
futureFoo(param1, param2).done(function(value) {/*value is [bar, 
baz]*/}, function(err) {})

This will be a bit odd for anyone used to using the library, but it is 
at least usable, unless 'bar' can be either an array or an object and 
'baz' is optional. Then the results are indeterminate. This problem 
could be avoided by allowing Futures to be resolved to one or more 
values and passing them via resolve (or accept) as a typical argument list:

resolve(value1, value2)

This would allow developers to more easily wrap existing node.js 
libraries, which would be particularly useful for those whom write code 
that runs on both the server and the client. It would also permit them 
to continue using a stylistic choice that has been adopted in the 
node.js community.

I think it's worth exploring whether or not this would be a useful 
addition to the Futures API -- and what the drawbacks may be. If 
compatibility with existing Promises/Futures libraries won't be too 
greatly harmed, or if this issue is deemed more important than some 
inconsistency with those existing libraries, then I would recommend that 
this behavior be supported. It would, in my opinion, aid in getting 
Futures more widely-adopted as it's one less barrier standing in the way 
of developers.

-Dave

-- 
Dave Longley
CTO
Digital Bazaar, Inc.

Received on Tuesday, 23 April 2013 18:09:05 UTC