resolve()/reject() on Promise subclasses and @@species

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

resolve()/reject() on Promise subclasses and @@species

Boris Zbarsky
I was just implementing subclassing of Promise in Gecko, when I realized
that given a Promise subclass MyPromise these two calls:

   MyPromise.race([])
   MyPromise.all([])

will take MyPromise[@@species] into account when creating the return
value, but these two calls:

   MyPromise.resolve()
   MyPromise.reject()

will not; they will invoke MyPromise itself, not MyPromise[@@species].

This is because
http://www.ecma-international.org/ecma-262/6.0/#sec-promise.all and
http://www.ecma-international.org/ecma-262/6.0/#sec-promise.race do the
whole @@species thing but
http://www.ecma-international.org/ecma-262/6.0/#sec-promise.reject and
http://www.ecma-international.org/ecma-262/6.0/#sec-promise.resolve do not.

Is this behavior intentional?  If so, I'd really like to understand the
reason for it.

-Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

Claude Pache

Le 29 oct. 2015 à 03:51, Boris Zbarsky <[hidden email]> a écrit :

I was just implementing subclassing of Promise in Gecko, when I realized that given a Promise subclass MyPromise these two calls:

 MyPromise.race([])
 MyPromise.all([])

will take MyPromise[@@species] into account when creating the return value, but these two calls:

 MyPromise.resolve()
 MyPromise.reject()

will not; they will invoke MyPromise itself, not MyPromise[@@species].

This is because http://www.ecma-international.org/ecma-262/6.0/#sec-promise.all and http://www.ecma-international.org/ecma-262/6.0/#sec-promise.race do the whole @@species thing but http://www.ecma-international.org/ecma-262/6.0/#sec-promise.reject and http://www.ecma-international.org/ecma-262/6.0/#sec-promise.resolve do not.

Is this behavior intentional?  If so, I'd really like to understand the reason for it.

-Boris


As I understand, the specified behaviour is an accident of history. Previously, `Promise.resolve()` and `Promise.reject()` used the species pattern in order to determine the constructor to be used, just as `Promise.all()` and `Promise.race()`. Then, at the last minute, it was decided that it wasn’t the best semantics for `Promise.resolve()`, and it was corrected. For `Promise.all()` and `Promise.race()`, the motivation wasn’t stronger than the lack of time.

Should it be corrected before @@species is widely implemented? I think so. The arguments I give are:

* Overall consistency in the language. Except for the two offending Promise static methods, all uses of `@@species` in the ES2015 spec (15 uses) are for the following pattern: Starting from one instance, one constructs a derived object for that instance. (The effective lookup of the @@species property is factored in the SpiecesConstructor and ArraySpeciesCreate abstract operations.)

* Also, in static methods like `Promise.all` and `Promise.race`, a constructor is explicitly provided by the user: simply use it. Compare with what is done for arrays:

Array.from(someArray) // use the Array constructor explicitly provided.
Array.of(x, y, z) // ditto

someArray.slice(0) // compute the constructor to be used through some algorithm involving @@species.
[].concat(x, y, z) // ditto

—Claude


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

Kevin Smith
Should it be corrected before @@species is widely implemented? I think so.

I agree, if feasible.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

Boris Zbarsky
In reply to this post by Claude Pache
On 10/30/15 1:19 PM, Claude Pache wrote:
> Should it be corrected before @@species is widely implemented?

Or implemented at all?  Chrome doesn't implement it yet.  My Firefox
tree does for Promise as of today, but I could just as easily drop it
from all/race if people prefer that.

-Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

Allen Wirfs-Brock
In reply to this post by Claude Pache
+1

Allen

On Oct 30, 2015, at 10:19 AM, Claude Pache <[hidden email]> wrote:


Le 29 oct. 2015 à 03:51, Boris Zbarsky <[hidden email]> a écrit :

I was just implementing subclassing of Promise in Gecko, when I realized that given a Promise subclass MyPromise these two calls:

 MyPromise.race([])
 MyPromise.all([])

will take MyPromise[@@species] into account when creating the return value, but these two calls:

 MyPromise.resolve()
 MyPromise.reject()

will not; they will invoke MyPromise itself, not MyPromise[@@species].

This is because http://www.ecma-international.org/ecma-262/6.0/#sec-promise.all and http://www.ecma-international.org/ecma-262/6.0/#sec-promise.race do the whole @@species thing but http://www.ecma-international.org/ecma-262/6.0/#sec-promise.reject and http://www.ecma-international.org/ecma-262/6.0/#sec-promise.resolve do not.

Is this behavior intentional?  If so, I'd really like to understand the reason for it.

-Boris


As I understand, the specified behaviour is an accident of history. Previously, `Promise.resolve()` and `Promise.reject()` used the species pattern in order to determine the constructor to be used, just as `Promise.all()` and `Promise.race()`. Then, at the last minute, it was decided that it wasn’t the best semantics for `Promise.resolve()`, and it was corrected. For `Promise.all()` and `Promise.race()`, the motivation wasn’t stronger than the lack of time.

Should it be corrected before @@species is widely implemented? I think so. The arguments I give are:

* Overall consistency in the language. Except for the two offending Promise static methods, all uses of `@@species` in the ES2015 spec (15 uses) are for the following pattern: Starting from one instance, one constructs a derived object for that instance. (The effective lookup of the @@species property is factored in the SpiecesConstructor and ArraySpeciesCreate abstract operations.)

* Also, in static methods like `Promise.all` and `Promise.race`, a constructor is explicitly provided by the user: simply use it. Compare with what is done for arrays:

Array.from(someArray) // use the Array constructor explicitly provided.
Array.of(x, y, z) // ditto

someArray.slice(0) // compute the constructor to be used through some algorithm involving @@species.
[].concat(x, y, z) // ditto

—Claude

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

C. Scott Ananian
As referenced in the cited thread
(https://esdiscuss.org/topic/performpromiseall#content-6) there are
actually two uses of the Promise constructor in the definition of
`all` and `race`.  To quote myself:

> [N]ote that the implementations given for `Promise.all` and `Promise.race` use Promises in two different ways: (1) every element of the array argument has `C1.resolve(elem).then(....)` applied to it, and (2) the result is constructed with `NewPromiseCapability(C2)`.  It's not entirely clear to me that C1 and C2 should be the same.  Consider the `TimeoutPromise`: do we want to apply a timeout to every element individually *and* to the result as a whole?
>
> It seems that C1 might use species (to avoid the timeout/weak reference), but C2 ignore it (to apply the timeout/weak reference to the final result)
>
>[...] [I]f we decided that `WeakPromise.all()` should return a `WeakPromise` then I'd suggest that we change step 6 from:
>> Let promiseCapability be NewPromiseCapability(C).
>to
>> Let promiseCapability be NewPromiseCapability(this).
>in both `Promise.all` and `Promise.race`, but leave the definition of C otherwise alone, so that internally-created promises honor the species.

The subtly of this detail of the spec was (for me at least) one of the
reasons I didn't push for a change to `Promise.all` and `Promise.race`
at the time.  And, as I wrote then, the current semantics do have a
plausible consistency, given future `Promise.prototype.all` and
`Promise.prototype.race` methods.

I'm certainly willing to reopen this for discussion, but I'd like to
see some hard thought given to the two separate uses in the
definition.
  --scott

On Fri, Oct 30, 2015 at 5:21 PM, Allen Wirfs-Brock
<[hidden email]> wrote:

> +1
>
> Allen
>
> On Oct 30, 2015, at 10:19 AM, Claude Pache <[hidden email]> wrote:
>
>
> Le 29 oct. 2015 à 03:51, Boris Zbarsky <[hidden email]> a écrit :
>
> I was just implementing subclassing of Promise in Gecko, when I realized
> that given a Promise subclass MyPromise these two calls:
>
>  MyPromise.race([])
>  MyPromise.all([])
>
> will take MyPromise[@@species] into account when creating the return value,
> but these two calls:
>
>  MyPromise.resolve()
>  MyPromise.reject()
>
> will not; they will invoke MyPromise itself, not MyPromise[@@species].
>
> This is because
> http://www.ecma-international.org/ecma-262/6.0/#sec-promise.all and
> http://www.ecma-international.org/ecma-262/6.0/#sec-promise.race do the
> whole @@species thing but
> http://www.ecma-international.org/ecma-262/6.0/#sec-promise.reject and
> http://www.ecma-international.org/ecma-262/6.0/#sec-promise.resolve do not.
>
> Is this behavior intentional?  If so, I'd really like to understand the
> reason for it.
>
> -Boris
>
>
> Relevant discussion: https://esdiscuss.org/topic/performpromiseall
>
> As I understand, the specified behaviour is an accident of history.
> Previously, `Promise.resolve()` and `Promise.reject()` used the species
> pattern in order to determine the constructor to be used, just as
> `Promise.all()` and `Promise.race()`. Then, at the last minute, it was
> decided that it wasn’t the best semantics for `Promise.resolve()`, and it
> was corrected. For `Promise.all()` and `Promise.race()`, the motivation
> wasn’t stronger than the lack of time.
>
> Should it be corrected before @@species is widely implemented? I think so.
> The arguments I give are:
>
> * Overall consistency in the language. Except for the two offending Promise
> static methods, all uses of `@@species` in the ES2015 spec (15 uses) are for
> the following pattern: Starting from one instance, one constructs a derived
> object for that instance. (The effective lookup of the @@species property is
> factored in the SpiecesConstructor and ArraySpeciesCreate abstract
> operations.)
>
> * Also, in static methods like `Promise.all` and `Promise.race`, a
> constructor is explicitly provided by the user: simply use it. Compare with
> what is done for arrays:
>
> Array.from(someArray) // use the Array constructor explicitly provided.
> Array.of(x, y, z) // ditto
>
> someArray.slice(0) // compute the constructor to be used through some
> algorithm involving @@species.
> [].concat(x, y, z) // ditto
>
> —Claude
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

Domenic Denicola
In reply to this post by Boris Zbarsky
I still think everything should go through @@species. I don't understand the utility of @@species if it is not uniformly applied to constructing new instances (in both instance and static methods). But it seems that ES15 decided to only use @@species for instance methods so I guess that's where we're stuck. 

 

From: "C. Scott Ananian" <[hidden email]>
Sent: Nov 5, 2015 3:20 AM
To: Allen Wirfs-Brock
Cc: es-discuss
Subject: Re: resolve()/reject() on Promise subclasses and @@species

As referenced in the cited thread
(https://esdiscuss.org/topic/performpromiseall#content-6) there are
actually two uses of the Promise constructor in the definition of
`all` and `race`.  To quote myself:

> [N]ote that the implementations given for `Promise.all` and `Promise.race` use Promises in two different ways: (1) every element of the array argument has `C1.resolve(elem).then(....)` applied to it, and (2) the result is constructed with `NewPromiseCapability(C2)`.  It's not entirely clear to me that C1 and C2 should be the same.  Consider the `TimeoutPromise`: do we want to apply a timeout to every element individually *and* to the result as a whole?
>
> It seems that C1 might use species (to avoid the timeout/weak reference), but C2 ignore it (to apply the timeout/weak reference to the final result)
>
>[...] [I]f we decided that `WeakPromise.all()` should return a `WeakPromise` then I'd suggest that we change step 6 from:
>> Let promiseCapability be NewPromiseCapability(C).
>to
>> Let promiseCapability be NewPromiseCapability(this).
>in both `Promise.all` and `Promise.race`, but leave the definition of C otherwise alone, so that internally-created promises honor the species.

The subtly of this detail of the spec was (for me at least) one of the
reasons I didn't push for a change to `Promise.all` and `Promise.race`
at the time.  And, as I wrote then, the current semantics do have a
plausible consistency, given future `Promise.prototype.all` and
`Promise.prototype.race` methods.

I'm certainly willing to reopen this for discussion, but I'd like to
see some hard thought given to the two separate uses in the
definition.
  --scott

On Fri, Oct 30, 2015 at 5:21 PM, Allen Wirfs-Brock
<[hidden email]> wrote:
> +1
>
> Allen
>
> On Oct 30, 2015, at 10:19 AM, Claude Pache <[hidden email]> wrote:
>
>
> Le 29 oct. 2015 à 03:51, Boris Zbarsky <[hidden email]> a écrit :
>
> I was just implementing subclassing of Promise in Gecko, when I realized
> that given a Promise subclass MyPromise these two calls:
>
>  MyPromise.race([])
>  MyPromise.all([])
>
> will take MyPromise[@@species] into account when creating the return value,
> but these two calls:
>
>  MyPromise.resolve()
>  MyPromise.reject()
>
> will not; they will invoke MyPromise itself, not MyPromise[@@species].
>
> This is because
> http://www.ecma-international.org/ecma-262/6.0/#sec-promise.all and
> http://www.ecma-international.org/ecma-262/6.0/#sec-promise.race do the
> whole @@species thing but
> http://www.ecma-international.org/ecma-262/6.0/#sec-promise.reject and
> http://www.ecma-international.org/ecma-262/6.0/#sec-promise.resolve do not.
>
> Is this behavior intentional?  If so, I'd really like to understand the
> reason for it.
>
> -Boris
>
>
> Relevant discussion: https://esdiscuss.org/topic/performpromiseall
>
> As I understand, the specified behaviour is an accident of history.
> Previously, `Promise.resolve()` and `Promise.reject()` used the species
> pattern in order to determine the constructor to be used, just as
> `Promise.all()` and `Promise.race()`. Then, at the last minute, it was
> decided that it wasn’t the best semantics for `Promise.resolve()`, and it
> was corrected. For `Promise.all()` and `Promise.race()`, the motivation
> wasn’t stronger than the lack of time.
>
> Should it be corrected before @@species is widely implemented? I think so.
> The arguments I give are:
>
> * Overall consistency in the language. Except for the two offending Promise
> static methods, all uses of `@@species` in the ES2015 spec (15 uses) are for
> the following pattern: Starting from one instance, one constructs a derived
> object for that instance. (The effective lookup of the @@species property is
> factored in the SpiecesConstructor and ArraySpeciesCreate abstract
> operations.)
>
> * Also, in static methods like `Promise.all` and `Promise.race`, a
> constructor is explicitly provided by the user: simply use it. Compare with
> what is done for arrays:
>
> Array.from(someArray) // use the Array constructor explicitly provided.
> Array.of(x, y, z) // ditto
>
> someArray.slice(0) // compute the constructor to be used through some
> algorithm involving @@species.
> [].concat(x, y, z) // ditto
>
> —Claude
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

C. Scott Ananian

Without rehashing the previous discussion, I totally disagree.  Having `Promise#resolve()` go through `@@species` made it totally useless.  It's also not in the spirit of the smalltalk species, which used very narrowly for instance methods like `map`, not for constructors.
  --scott


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

C. Scott Ananian

(Sorry, that should have been `Promise.resolve`, not `Promise#resolve`.)
  --scott


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

Boris Zbarsky
In reply to this post by Domenic Denicola
On 11/4/15 9:36 PM, Domenic Denicola wrote:
> But it seems that
> ES15 decided to only use @@species for instance methods

Except it also uses it for Promise.all and Promise.race.

-Boris

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

C. Scott Ananian

Again, the reasoning at the time was that `Promise.all(x)` could be considered sugar for `Promise.resolve(x).all()` in ES7, and so `Promise.all` was "really" an instance method after all.  Again, I could support a change, I'm just saying it wasn't totally crazy, and no one made any objection at the time.

But this is really rehashing the previous discussion.
  --scott


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

Boris Zbarsky
On 11/4/15 10:29 PM, C. Scott Ananian wrote:
> Again, the reasoning at the time was that `Promise.all(x)` could be
> considered sugar for `Promise.resolve(x).all()` in ES7, and so
> `Promise.all` was "really" an instance method after all.

OK, but note that the behavior of the two is different (or at least the
behavior of @@species is different between Promise.prototype.then and
Promise.all).  Specifically if I have:

   class MyPromise extends Promise {
     static get [Symbol.species]() { return undefined; }
   }

then MyPromise.all() will return a MyPromise but
MyPromise.resolve(x).then() will return a Promise, because
SpeciesConstructor falls back to "defaultConstructor", not "C", if
Get(@@species) returns null-or-undefined, while Promise.all()/race()
fall back to "C".

> I'm just saying it wasn't totally crazy, and no one
> made any objection at the time.

Sure.  Also, no one has implemented any of this stuff yet.  ;)  I was
just implementing it and was confused by the various inconsistencies.  I
can implement it as written, of course, but I wanted to double-check
that I wasn't misunderstanding something.

-Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

C. Scott Ananian

The spec has been implemented as is by both `es6-shim` and `core-js`, and there are plenty of users of these.  So it's not correct to say that it hasn't been implemented yet; folks aren't waiting for the browsers.

The differing behaviors in the null-or-undefined case should probably be remedied, at least.

But I am in favor of making a change to all/race to move them away from @@species, see my previous message for the exact wording proposal which changes step 6.  I'd appreciate comments on that.
  --scott


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

Boris Zbarsky
On 11/4/15 11:22 PM, C. Scott Ananian wrote:
> see my previous message for the exact wording proposal which
> changes step 6.

https://esdiscuss.org/topic/performpromiseall#content-6 you mean?

I don't have a strong opinion on it, honestly.  The existence of the
intermediate promises in all/race seems mostly to be a specification
device to make it easier to deal with people passing in
not-thenable-at-all values, from my point of view, so I'm not sure I
have a principled opinion on how they should be constructed.

-Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

C. Scott Ananian

Unfortunately, it's not just a specification device, it has a real effect on the behavior of Promise subclasses.  In the case of TimeoutPromise, for instance, it affects whether the timeouts apply to *each promise in the array* or just to the final result Promise.

I'm hearing through the grapevine (https://github.com/tc39/ecma262/issues/151) that it has been decided to change the behavior of Promise.all/race. Have you decided to adopt the spec language I proposed above?  There has been precious little actual discussion of it, certainly not enough for me to claim any sort of consensus has been reached (except perhaps by default, since no one has  advocated for alternatives).
  --scott

On 11/4/15 11:22 PM, C. Scott Ananian wrote:
see my previous message for the exact wording proposal which
changes step 6.

https://esdiscuss.org/topic/performpromiseall#content-6 you mean?

I don't have a strong opinion on it, honestly.  The existence of the intermediate promises in all/race seems mostly to be a specification device to make it easier to deal with people passing in not-thenable-at-all values, from my point of view, so I'm not sure I have a principled opinion on how they should be constructed.

-Boris

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

Domenic Denicola

All uses of @@species are to be removed from Promise.race and Promise.all. The committee achieved consensus on this, without you.




From: es-discuss <[hidden email]> on behalf of C. Scott Ananian <[hidden email]>
Sent: Wednesday, November 18, 2015 18:15
To: Boris Zbarsky
Cc: [hidden email] list
Subject: Re: resolve()/reject() on Promise subclasses and @@species
 

Unfortunately, it's not just a specification device, it has a real effect on the behavior of Promise subclasses.  In the case of TimeoutPromise, for instance, it affects whether the timeouts apply to *each promise in the array* or just to the final result Promise.

I'm hearing through the grapevine (https://github.com/tc39/ecma262/issues/151) that it has been decided to change the behavior of Promise.all/race. Have you decided to adopt the spec language I proposed above?  There has been precious little actual discussion of it, certainly not enough for me to claim any sort of consensus has been reached (except perhaps by default, since no one has  advocated for alternatives).

Remove @@species lookup from Promise.all() and Promise ...
Remove @@species lookup from Promise.all() and Promise.race() #151


  --scott

On 11/4/15 11:22 PM, C. Scott Ananian wrote:
see my previous message for the exact wording proposal which
changes step 6.

https://esdiscuss.org/topic/performpromiseall#content-6 you mean?

I don't have a strong opinion on it, honestly.  The existence of the intermediate promises in all/race seems mostly to be a specification device to make it easier to deal with people passing in not-thenable-at-all values, from my point of view, so I'm not sure I have a principled opinion on how they should be constructed.

-Boris

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: resolve()/reject() on Promise subclasses and @@species

C. Scott Ananian
On Wed, Nov 18, 2015 at 6:50 PM, Domenic Denicola <[hidden email]> wrote:

All uses of @@species are to be removed from Promise.race and Promise.all. The committee achieved consensus on this, without you.


To be precise, steps 3-5 are to be removed entirely from Promise.all (25.4.4.1) and Promise.race (25.4.4.3)?

So for `WeakPromise.all([ p1, {} ])` a weak reference would be held to p1's value, the new {} object, *and* the array result of the `all`.
Similarly, `TimeoutPromise.all([ p1, p2 ])` would put timeouts on p1 and p2 *and* on the array result, so the semantics are the same as:
`TimeoutPromise.resolve(TimeoutPromise.all([ TimeoutPromise.resolve(p1), TimeoutPromise.resolve(p2) ]))`.

I'm not objecting to this semantics, necessarily, I'm just surprised it wasn't proposed or discussed on the public mailing list before adoption.
 --scott

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss