Skip Menu |

This queue is for tickets about the AnyEvent-XSPromises CPAN distribution.

Report information
The Basics
Id: 131196
Status: rejected
Priority: 0/
Queue: AnyEvent-XSPromises

People
Owner: Nobody in particular
Requestors: felipe [...] felipegasper.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: $deferred->resolve($promise) neglects to resolve a promise
Date: Wed, 18 Dec 2019 12:26:45 -0500
To: bug-AnyEvent-XSPromises [...] rt.cpan.org
From: Felipe Gasper <felipe [...] felipegasper.com>
===== #!/usr/bin/env perl use strict; use warnings; use AnyEvent::XSPromises (); use Data::Dumper; my $cv = AnyEvent->condvar(); my $deferred1 = AnyEvent::XSPromises::deferred(); my $p = $deferred1->promise(); my $pp = $p->then( sub { print Dumper( promise1 => shift ); $cv->(); } ); my $deferred2 = AnyEvent::XSPromises::deferred(); my $p2 = $deferred2->promise(); $deferred1->resolve($p2); $cv->recv(); ===== Show quoted text
> perl anyevent_xspromises_bug.pl
$VAR1 = 'promise1'; $VAR2 = bless( do{\(my $o = '140656308834288')}, 'AnyEvent::XSPromises::PromisePtr' ); --------- Compare to the following JS code, which shows that a promise given to the resolve callback/function is itself resolved; that resolution, not the promise itself, is what is given to the on-resolve handler: ===== #!/usr/bin/env node "use strict"; var res; var p = new Promise( (y) => { res = y } ); var res2; var p2 = new Promise( (y) => { res2 = y } ); res(p2); p.then( (v) => console.log("got", v) ); res2( Promise.resolve(234) ); ===== Show quoted text
> node promise.js
got 234 --------- Thank you in advance for looking into this! -Felipe Gasper
On Wed Dec 18 13:41:42 2019, felipe@felipegasper.com wrote: Show quoted text
> ===== > #!/usr/bin/env perl > > use strict; > use warnings; > > use AnyEvent::XSPromises (); > use Data::Dumper; > > my $cv = AnyEvent->condvar(); > > my $deferred1 = AnyEvent::XSPromises::deferred(); > my $p = $deferred1->promise(); > my $pp = $p->then( sub { print Dumper( promise1 => shift ); $cv->(); } > ); > > my $deferred2 = AnyEvent::XSPromises::deferred(); > my $p2 = $deferred2->promise(); > > $deferred1->resolve($p2); > > $cv->recv(); > =====
> > perl anyevent_xspromises_bug.pl
> $VAR1 = 'promise1'; > $VAR2 = bless( do{\(my $o = '140656308834288')}, > 'AnyEvent::XSPromises::PromisePtr' ); > > --------- > > Compare to the following JS code, which shows that a promise given to > the resolve callback/function is itself resolved; that resolution, not > the promise itself, is what is given to the on-resolve handler: > > ===== > #!/usr/bin/env node > > "use strict"; > > var res; > var p = new Promise( (y) => { res = y } ); > > var res2; > var p2 = new Promise( (y) => { res2 = y } ); > > res(p2); > > p.then( (v) => console.log("got", v) ); > > res2( Promise.resolve(234) ); > =====
> > node promise.js
> got 234 > > --------- > > Thank you in advance for looking into this! > > -Felipe Gasper
Ha, fun. This is not a bug, and it is not a feature. This library implements the Promises/A+ specification, which does not specify how the creation of promises should happen. The "deferred" API is for library builders, like Cassandra::Client, Net::Kafka, AnyEvent::YACurl, etc. The presumption is that they have an AnyEvent-based library available to them already, and want to turn the callback-style API into a promise-style API. They would then create a deferred object, and in the callback resolve/reject it. Chaining with existing resolved promises should be done via then(), and deferred objects should be kept reserved for library authors. If someone already has a promise available and intends to chain, the creation of a deferred object only to resolve it with an existing promise is something I consider unwanted. Chain it properly instead. In other words, this is expected behavior.
Subject: Re: [rt.cpan.org #131196] $deferred->resolve($promise) neglects to resolve a promise
Date: Wed, 18 Dec 2019 14:29:31 -0500
To: bug-AnyEvent-XSPromises [...] rt.cpan.org
From: Felipe Gasper <felipe [...] felipegasper.com>
Show quoted text
> On Dec 18, 2019, at 1:57 PM, Tom van der Woerdt via RT <bug-AnyEvent-XSPromises@rt.cpan.org> wrote: > > <URL: https://rt.cpan.org/Ticket/Display.html?id=131196 > > > On Wed Dec 18 13:41:42 2019, felipe@felipegasper.com wrote:
>> ===== >> #!/usr/bin/env perl >> >> use strict; >> use warnings; >> >> use AnyEvent::XSPromises (); >> use Data::Dumper; >> >> my $cv = AnyEvent->condvar(); >> >> my $deferred1 = AnyEvent::XSPromises::deferred(); >> my $p = $deferred1->promise(); >> my $pp = $p->then( sub { print Dumper( promise1 => shift ); $cv->(); } >> ); >> >> my $deferred2 = AnyEvent::XSPromises::deferred(); >> my $p2 = $deferred2->promise(); >> >> $deferred1->resolve($p2); >> >> $cv->recv(); >> =====
>>> perl anyevent_xspromises_bug.pl
>> $VAR1 = 'promise1'; >> $VAR2 = bless( do{\(my $o = '140656308834288')}, >> 'AnyEvent::XSPromises::PromisePtr' ); >> >> --------- >> >> Compare to the following JS code, which shows that a promise given to >> the resolve callback/function is itself resolved; that resolution, not >> the promise itself, is what is given to the on-resolve handler: >> >> ===== >> #!/usr/bin/env node >> >> "use strict"; >> >> var res; >> var p = new Promise( (y) => { res = y } ); >> >> var res2; >> var p2 = new Promise( (y) => { res2 = y } ); >> >> res(p2); >> >> p.then( (v) => console.log("got", v) ); >> >> res2( Promise.resolve(234) ); >> =====
>>> node promise.js
>> got 234 >> >> --------- >> >> Thank you in advance for looking into this! >> >> -Felipe Gasper
> > > Ha, fun. > > This is not a bug, and it is not a feature. This library implements the Promises/A+ specification, which does not specify how the creation of promises should happen. > > The "deferred" API is for library builders, like Cassandra::Client, Net::Kafka, AnyEvent::YACurl, etc. The presumption is that they have an AnyEvent-based library available to them already, and want to turn the callback-style API into a promise-style API. They would then create a deferred object, and in the callback resolve/reject it. > > Chaining with existing resolved promises should be done via then(), and deferred objects should be kept reserved for library authors. > > If someone already has a promise available and intends to chain, the creation of a deferred object only to resolve it with an existing promise is something I consider unwanted. Chain it properly instead. > > In other words, this is expected behavior.
Ah, I see now. From the A+ spec: Note that the tests will never pass a promise or a thenable as a resolution. That means that we never use the promise- or thenable-accepting forms of the resolve operation directly, and instead only use the direct fulfillment operation, since fulfill and resolve are equivalent when not given a thenable. Thank you! -FG