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

Re: Deprecating Future's .then()

From: Mark S. Miller <erights@google.com>
Date: Sun, 16 Jun 2013 18:13:44 -0700
Message-ID: <CABHxS9iOb2+yZ933VUvYT5k_SumvEncxoZD233cPj6nVdk8x-g@mail.gmail.com>
To: Sean Hogan <shogun70@westnet.com.au>
Cc: "Tab Atkins Jr." <jackalmage@gmail.com>, "www-dom@w3.org" <www-dom@w3.org>, "public-script-coord@w3.org" <public-script-coord@w3.org>, Anne van Kesteren <annevk@annevk.nl>
Hi Sean, there's nothing undefined about this. It just doesn't do what you
might want.

In discussing AP2 with Tab, Anne, and Alex, I found we needed a new
terminological distinction, between being "accepted" and "fulfilled". This
is best understood in terms of when .then vs .flatMap call their first
callback:

    p.then(onFulfilled)
    p.flatMap(onAccepted)

The key thing about AP2 is that all assimilation and recursive flattening
need only happen when .then calls its onFulfilled callback. So the state of
being ready to call the onFulfilled callback is the state that should be
named "fulfilled". A promise-for-a-pending-promise is not yet fulfilled, as
doing a .then on it won't call the first callback until its inner promise
is fulfilled. So, ironically given the history, it makes sense to call the
one-level unconditional lift operator "accept" rather than "fulfill", and
to say that .flatMap triggers when a promise has been accepted.

With .then doing full recursive flattening and assimilation, nothing else
needs to. Promise.resolve need only do a brand check and a single
brand-based auto-lifting. .then, on the results of its callbacks, need only
do a brand check and auto-flatten the results. (In the same sense that
.flatMap flattens its results.)

So concretely, in terms of your example, if we interpret AP2 in this
conservative manner, then the promise already returned by the .then becomes
accepted with Data, but not yet fulfilled since Data has a .then method.
Call this returned promise dP.

dP.flatMap(d => console.log(d)) // will log your Data object
// the returned promise will be resolved to the result of console.log.

dP.then(d => console.log(d)) // will never log anything
// will never resolve the promise it returned

The reason why .then acts like this on your example is that, on seeing that
dP is resolved to a thenable, will invoke its .then method with resolver
and rejector functions, waiting for these to be called. Since Data's .then
doesn't call these, that .then doesn't make any further progress.




On Sun, Jun 16, 2013 at 5:13 PM, Sean Hogan <shogun70@westnet.com.au> wrote:

> On 3/06/13 9:37 AM, Sean Hogan wrote:
>
>> On 20/05/13 12:05 PM, Tab Atkins Jr. wrote:
>>
>>> On Sun, May 19, 2013 at 6:04 PM, Sean Hogan <shogun70@westnet.com.au>
>>> wrote:
>>>
>>>  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.
>>>>>
>>>>
>>>>
>>>> A contrived example:
>>>>
>>>>      var Data = {
>>>>          x: 1,
>>>>          y: 2,
>>>>          then: function() { }
>>>>      }
>>>>
>>>>      Future.accept()
>>>>      .then(function() {
>>>>          return Data;
>>>>      })
>>>>      .done(function(value) {
>>>>          someExternalCodeExpectingData(**value);
>>>>      });
>>>>
>>>> This chain will stall (silently) because `Data` will be treated as a
>>>> Promise
>>>> object.
>>>> Replace the .then() call with .thenfu and the following won't stall:
>>>>
>>>>      .thenfu(function(value) {
>>>>          this.accept(Data);
>>>>      })
>>>>
>>> Yes, this is why I don't understand.  You can do the same thing in
>>> Futures, once Anne fixes the spec like he's saying he will, by doing:
>>>
>>> .then(function(val) {
>>>    return Future.accept(Data);
>>> }
>>>
>>> This unconditionally stores the Data object in the Future, without
>>> regards to whether Data is a thenable, a native Future, or a plain
>>> value.
>>>
>>>
>>>
>>
>> Since the spec hasn't been updated, is there more info on how
>> `Future.accept()` will be fixed to support that code sample?
>>
>>
>>
>>
> Since the spec isn't going to support this scenario, shouldn't there be a
> note about it? Something like:
>
> If a .then() or .catch() callback returns an object that has a .then()
> method that is incompatible with DOM Promises (possibly because it is not a
> Promise-like object) then the behavior of .then()/.catch() is undefined.
>
>
>
>


-- 
    Cheers,
    --MarkM
Received on Monday, 17 June 2013 01:14:11 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 20 October 2015 10:46:21 UTC