- From: Mark S. Miller <erights@google.com>
- Date: Sun, 16 Jun 2013 18:13:44 -0700
- 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>
- Message-ID: <CABHxS9iOb2+yZ933VUvYT5k_SumvEncxoZD233cPj6nVdk8x-g@mail.gmail.com>
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