W3C home > Mailing lists > Public > www-dom@w3.org > April to June 2013

RE: Resolving Futures w/multiple values

From: Domenic Denicola <domenic@domenicdenicola.com>
Date: Tue, 23 Apr 2013 18:20:12 +0000
To: Dave Longley <dlongley@digitalbazaar.com>, "www-dom@w3.org" <www-dom@w3.org>
CC: Anne van Kestern <annevk@annevk.nl>, "slightlyoff@chromium.org" <slightlyoff@chromium.org>
Message-ID: <B4AE8F4E86E26C47AC407D49872F6F9F7EF4BF96@BY2PRD0510MB354.namprd05.prod.outlook.com>
Just as yoy can't return (or throw) multiple values from a function, so you can't fulfill (or reject) a promise with multiple values. Promises model asynchronous return/throw and the associated call stack, so multiple fulfillment values would be nonsensical.

You may find http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/ helpful?
From: Dave Longley<mailto:dlongley@digitalbazaar.com>
Sent: 4/23/2013 14:10
To: www-dom@w3.org<mailto:www-dom@w3.org>
Cc: Anne van Kestern<mailto:annevk@annevk.nl>; slightlyoff@chromium.org<mailto:slightlyoff@chromium.org>
Subject: Resolving Futures w/multiple values


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 Longley
Digital Bazaar, Inc.
Received on Tuesday, 23 April 2013 18:20:48 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 22:37:02 UTC