Where'd Promise#done go?

Claus Reinke claus.reinke at talk21.com
Thu Jun 20 15:19:18 PDT 2013

>> 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=>

    ... ) ) ) ) )

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) ) ) ) };
    ...' ) )

(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.


More information about the es-discuss mailing list