@@ -674,38 +674,21 @@ promise_test(async t => {
674
674
675
675
// This test is a more chaotic version of the above. It ensures that a single
676
676
// Observable can handle multiple in-flight subscriptions to the same underlying
677
- // async iterable without the two subscriptions competing.
678
- //
679
- // This test is added because it is easy to imagine an implementation whereby
680
- // upon subscription, the Observable's internal subscribe callback takes the
681
- // underlying async iterable object, and simply pulls the async iterator off of
682
- // it (by invoking `@@asyncIterator`), and saves it alongside the underlying
683
- // async iterable. This async iterator would be used to manage values as they
684
- // are asynchronously emitted from the underlying object, but this value can get
685
- // OVERWRITTEN by a brand new subscription that comes in before the first
686
- // subscription has completed. In a broken implementation, this overwriting
687
- // would prevent the first subscription from ever completing.
677
+ // async iterable without the two subscriptions competing. It asserts that the
678
+ // asynchronous values are pushed to the observers in the correct order.
688
679
promise_test ( async t => {
689
680
const async_iterable = {
690
- slow : true ,
691
681
[ Symbol . asyncIterator ] ( ) {
692
- // The first time @@asyncIterator is called, `shouldBeSlow` is true, and
693
- // when the return object takes closure of it, all values are emitted
694
- // SLOWLY asynchronously. The second time, `shouldBeSlow` is false, and
695
- // all values are emitted FAST but still asynchronous.
696
- const shouldBeSlow = this . slow ;
697
- this . slow = false ;
698
-
699
682
return {
700
683
val : 0 ,
701
684
next ( ) {
702
685
// Returns a Promise that resolves in a random amount of time less
703
686
// than a second.
704
687
return new Promise ( resolve => {
705
688
t . step_timeout ( ( ) => resolve ( {
706
- value : ` ${ this . val } - ${ shouldBeSlow ? 'slow' : 'fast' } ` ,
689
+ value : this . val ,
707
690
done : this . val ++ === 4 ? true : false ,
708
- } ) , shouldBeSlow ? 200 : 0 ) ;
691
+ } ) , 200 ) ;
709
692
} ) ;
710
693
} ,
711
694
} ;
@@ -715,30 +698,46 @@ promise_test(async t => {
715
698
const results = [ ] ;
716
699
const source = Observable . from ( async_iterable ) ;
717
700
718
- const subscribeFunction = function ( resolve , reject ) {
701
+ const promise = new Promise ( resolve => {
719
702
source . subscribe ( {
720
- next : v => results . push ( v ) ,
721
- complete : ( ) => resolve ( ) ,
703
+ next : v => {
704
+ results . push ( `${ v } -first-sub` ) ;
705
+
706
+ // Half-way through the first subscription, start another subscription.
707
+ if ( v === 0 ) {
708
+ source . subscribe ( {
709
+ next : v => results . push ( `${ v } -second-sub` ) ,
710
+ complete : ( ) => {
711
+ results . push ( 'complete-second-sub' ) ;
712
+ resolve ( ) ;
713
+ }
714
+ } ) ;
715
+ }
716
+ } ,
717
+ complete : ( ) => {
718
+ results . push ( 'complete-first-sub' ) ;
719
+ resolve ( ) ;
720
+ }
722
721
} ) ;
722
+ } ) ;
723
723
724
- // A broken implementation will rely on this timeout.
725
- t . step_timeout ( ( ) => reject ( 'TIMEOUT' ) , 3000 ) ;
726
- }
727
-
728
- const slow_promise = new Promise ( subscribeFunction ) ;
729
- const fast_promise = new Promise ( subscribeFunction ) ;
730
- await Promise . all ( [ slow_promise , fast_promise ] ) ;
724
+ await promise ;
731
725
assert_array_equals ( results , [
732
- '0-fast' ,
733
- '1-fast' ,
734
- '2-fast' ,
735
- '3-fast' ,
736
- '0-slow' ,
737
- '1-slow' ,
738
- '2-slow' ,
739
- '3-slow' ,
726
+ '0-first-sub' ,
727
+
728
+ '1-first-sub' ,
729
+ '1-second-sub' ,
730
+
731
+ '2-first-sub' ,
732
+ '2-second-sub' ,
733
+
734
+ '3-first-sub' ,
735
+ '3-second-sub' ,
736
+
737
+ 'complete-first-sub' ,
738
+ 'complete-second-sub' ,
740
739
] ) ;
741
- } , "from(): Asynchronous iterable multiple in-flight subscriptions competing " ) ;
740
+ } , "from(): Asynchronous iterable multiple in-flight subscriptions" ) ;
742
741
// This test is like the above, ensuring that multiple subscriptions to the same
743
742
// sync-iterable-converted-Observable can exist at a time. Since sync iterables
744
743
// push all of their values to the Observable synchronously, the way to do this
@@ -751,24 +750,27 @@ test(() => {
751
750
const source = Observable . from ( array ) ;
752
751
source . subscribe ( {
753
752
next : v => {
754
- results . push ( v ) ;
753
+ results . push ( ` ${ v } -first-sub` ) ;
755
754
if ( v === 3 ) {
756
755
// Pushes all 5 values to `results` right after the first instance of `3`.
757
756
source . subscribe ( {
758
- next : v => results . push ( v ) ,
759
- complete : ( ) => results . push ( 'inner complete' ) ,
757
+ next : v => results . push ( ` ${ v } -second-sub` ) ,
758
+ complete : ( ) => results . push ( 'complete-second-sub ' ) ,
760
759
} ) ;
761
760
}
762
761
} ,
763
- complete : ( ) => results . push ( 'outer complete' ) ,
762
+ complete : ( ) => results . push ( 'complete-first-sub ' ) ,
764
763
} ) ;
765
764
766
765
assert_array_equals ( results , [
767
- 1 , 2 , 3 ,
768
- 1 , 2 , 3 , 4 , 5 , 'inner complete' ,
769
- 4 , 5 , 'outer complete'
766
+ // These values are pushed when there is only a single subscription.
767
+ '1-first-sub' , '2-first-sub' , '3-first-sub' ,
768
+ // These values are pushed in the correct order, for two subscriptions.
769
+ '4-first-sub' , '4-second-sub' ,
770
+ '5-first-sub' , '5-second-sub' ,
771
+ 'complete-first-sub' , 'complete-second-sub' ,
770
772
] ) ;
771
- } , "from(): Sync iterable multiple in-flight subscriptions competing " ) ;
773
+ } , "from(): Sync iterable multiple in-flight subscriptions" ) ;
772
774
773
775
promise_test ( async ( ) => {
774
776
const async_generator = async function * ( ) {
0 commit comments