W3C home > Mailing lists > Public > public-script-coord@w3.org > April to June 2013

Re: Deprecating Future's .then()

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Sun, 19 May 2013 15:32:36 -0700
Message-ID: <CAAWBYDBK7tYi6nV=t_n7o29phZHx3den+6q5hMdYhVMcCcmw_A@mail.gmail.com>
To: Sean Hogan <shogun70@westnet.com.au>
Cc: "www-dom@w3.org" <www-dom@w3.org>, "public-script-coord@w3.org" <public-script-coord@w3.org>, Anne van Kesteren <annevk@annevk.nl>
I *really* don't like this proposal.  Comments inline, as usual.

On Sat, May 18, 2013 at 3:09 PM, Sean Hogan <shogun70@westnet.com.au> wrote:
> BENEFITS:
>
> The main benefits of this addition are:
>
> a. consistency in the way futures are initialized and resolved - that is,
> resolving is always asynchronous via `resolver.accept|reject`.

This comes at the expense of easier and simpler code to write in the
common case, when you're receiving an already-built future and are
just acting on it via .then().  You can no longer just return a value
like a normal function; you are forced to call `this.accept()`.

Given that you have to reject the promise based on uncaught errors in
the callback anyway (or else you lose an important quality of
promises), `this.reject()` doesn't give you anything
(`this.reject(val)` is identical to `throw val`, but longer).

You've also removed the ability to do `this.resolve()`, for some
reason.  This isn't explained at all in your proposal, which makes me
assume that you don't understand what it's used for.  This means you
can't force your promise to delegate to another promise, as you can do
today.

Finally, you're overriding `this` to be the future's resolver, thus
ruling out any possibility of passing in class methods that want to
refer to the class instance when processing the future's value.  It's
unclear what the effect of this would be on hard-bound methods, as
well.

> b. easily mix with non-Promise asynchronous code without creating yet
> another a new Future

Why is this a problem?  It's very simple code:

f.then(function(val) {
  var resolver, newf = new Future(function(r){ resolver = r; });
  doAsyncStuff(resolver);
  return newf;
}

Here's the code in your proposal:

f.then(function(val) {
  doAsyncStuff(this);
  return;
}

Slightly simpler, but not significantly.  We could even paper over
this with a convenience method that created a new Future and returned
a promise/resolver pair, making the gap even smaller.

There is a new Future getting created, but if all you do is return it
immediately, it'll get GCed away when appropriate.

> c. `then` doesn't need to be the feature-test for Promise objects,
> and doesn't need to be  a forbidden method of non-Promise objects.

I don't understand how this is a result of your proposal.

~TJ
Received on Sunday, 19 May 2013 22:33:36 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 21:37:49 UTC