Where'd Promise#done go?

Mark S. Miller erights at google.com
Thu Jun 20 19:03:44 PDT 2013


On Thu, Jun 20, 2013 at 3:19 PM, Claus Reinke <claus.reinke at talk21.com>wrote:

>  Naively translating the standard pipeline example gives
>>>
>>>    x.a().then( t1=>
>>>    y.b().then( t2=>
>>>    t1.c(t2).then( t3=>
>>>    ... ) ) )
>>> ..
>>> This is naïve because the synchronous method calls should really
>>> be asynchronous message sends. If we assume local proxies that
>>> forward local method calls to remote objects and remote results
>>> to local callbacks, then y.b() will not start until t1 comes back.
>>>
>>> But if t1 is itself a promise, then it can come back immediately,
>>>
>>
>> I think this is what you are missing. If x.a() returns, for example, an
>> int, then x!a() returns a promise that will turn out to be a
>> promise-for-int. In that case, x!a().then(t1 => ...t1...), the callback
>> will only be invoked with t1 bound to the int itself. This can't happen
>> prior to the completion of the round trip.
>>
>
> As I was saying, that restriction is not necessary - it is a consequence
> of the flatten-nested-promises-**before-then-callback philosophy. Instead,
> the local proxy can send the remote message and locally pass a receiver
> promise to its callback. That way, the callback can start to run until it
> actually needs to query the receiver promise for a value.
>
> If we did this for the .a and .b calls, the translation would change to
>
>    x.a().then( t1p=>
>    y.b().then( t2p=>
>
>    t1p.then( t1=>
>    t2p.then( t2=>
>    t1.c(t2).then( t3=>
>

This corresponds only to running .a and .b overlapped. Since .c isn't run
until both the .a and .b round trips complete, this isn't promise
pipelining. This isn't just a matter of definitions. You lose most of the
important optimization if all you're doing is overlapping independent
requests.



>
>    ... ) ) ) ) )
>
> and the .b call could be triggered before the .a call roundtrip completes.
> If we want to push the "lazy-evalutation" into the ... part, things get
> more interesting, as one would need to model the data-dependencies
> and delay looking at t1p/t2p further. One could define an inline
> then-able to capture this:
>
>    x.a().then( t1p=>
>    y.b().then( t2p=>
>    let t3p = { then(cb): { t1p.then( t1=> t2p.then( t2=>
>                                        t1.c(t2).then( t3=> cb(t3) ) ) ) };
>    ...' ) )
>

I can't yet respond to this because I don't understand your notation. What
does "{ then(cb): " mean?



>
> (where ...' is ..., transformed to work with a promise t3p instead of t3)
>
> Now, waiting for the .a and .b roundtrips would be delayed until
> some code in ...' actually needs to look at t3. One could further
> delay looking at t2 if t1.c() could deal with a promise t2p.
>
> This additional flexibility is not available in a flat-promise design,
> which is why I think such a design is a mistake. Of course, even
> if one wants to accept the restrictions of a flat-promise design,
> the flattening should happen in promise construction, not in .then.
>
> Claus
>
>
>


-- 
    Cheers,
    --MarkM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130620/e2ae6bf4/attachment.html>


More information about the es-discuss mailing list