@@ -8,59 +8,42 @@ function create(coroutine) {
88 super ( props ) ;
99 this . state = { view : null } ;
1010 this . iterator = null ;
11- this . mounted = false ;
1211 }
1312
1413 iterate ( props ) {
1514 let target = coroutine ( props ) ;
1615
1716 this . iterator = target ;
1817
19- let updater = view => {
20- if ( this . mounted && this . iterator === target ) {
21- this . setState ( { view } ) ;
22- }
23- } ;
18+ let shouldStop = ( ) => this . iterator !== target ;
19+ let updateView = view => this . setState ( { view } ) ;
2420
2521 if ( isPromiseLike ( target ) ) {
2622 // coroutine is Async Function, awaiting for the final result
27- return target . then ( updater ) ;
23+ return target . then ( value => shouldStop ( ) || updateView ( value ) ) ;
2824 } else {
2925 let step = this . iterator . next ( ) ;
3026
3127 if ( isPromiseLike ( step ) ) {
3228 // coroutine is Async Generator, rendering every time it yields
33- return resolveAsyncIterator ( this . iterator , step , updater ) ;
29+ return resolveAsyncIterator ( this . iterator , step , updateView , shouldStop ) ;
3430 } else {
3531 // coroutine is Sync Generator, rendering the final result, awaiting yielded promises
36- return resolveSyncIterator ( this . iterator , step , updater ) ;
32+ return resolveSyncIterator ( this . iterator , step , updateView , shouldStop ) ;
3733 }
3834 }
3935 }
4036
4137 componentDidMount ( ) {
42- this . mounted = true ;
4338 return this . iterate ( this . props ) ;
4439 }
4540
4641 componentDidUpdate ( prevProps ) {
47- if ( ! arePropsEqual ( this . props , prevProps ) ) {
48- if ( this . iterator && this . iterator . return ) {
49- this . iterator . return ( ) ;
50- }
51-
52- if ( this . mounted ) {
53- this . iterate ( this . props ) ;
54- }
55- }
42+ return arePropsEqual ( this . props , prevProps ) || this . iterate ( this . props ) ;
5643 }
5744
5845 componentWillUnmount ( ) {
59- if ( this . iterator && this . iterator . return ) {
60- this . iterator . return ( ) ;
61- }
62-
63- this . mounted = false ;
46+ this . iterator = null ;
6447 }
6548
6649 render ( ) {
@@ -73,29 +56,36 @@ function create(coroutine) {
7356 return Coroutine ;
7457}
7558
76- function resolveSyncIterator ( i , step , cb ) {
59+ function resolveSyncIterator ( i , step , cb , shouldStop ) {
60+ if ( shouldStop ( ) ) {
61+ return i . return ( ) ;
62+ }
7763 if ( ! step . done ) {
7864 if ( isPromiseLike ( step . value ) ) {
7965 return step . value
80- . then ( data => resolveSyncIterator ( i , i . next ( data ) , cb ) )
81- . catch ( error => resolveSyncIterator ( i , i . throw ( error ) , cb ) ) ;
66+ . then ( data => resolveSyncIterator ( i , i . next ( data ) , cb , shouldStop ) )
67+ . catch ( error => resolveSyncIterator ( i , i . throw ( error ) , cb , shouldStop ) ) ;
8268 } else {
8369 let isErrorLike = step . value instanceof Error ;
8470 let nextStep = isErrorLike ? i . throw ( step . value ) : i . next ( step . value ) ;
85- return resolveSyncIterator ( i , nextStep , cb ) ;
71+ return resolveSyncIterator ( i , nextStep , cb , shouldStop ) ;
8672 }
8773 } else {
8874 return cb ( step . value ) ;
8975 }
9076}
9177
92- function resolveAsyncIterator ( i , step , cb ) {
78+ function resolveAsyncIterator ( i , step , cb , shouldStop ) {
9379 step . then ( data => {
80+ if ( shouldStop ( ) ) {
81+ return i . return ( ) ;
82+ }
83+
9484 if ( data . value !== undefined ) {
9585 cb ( data . value ) ;
9686 }
9787
98- return ! data . done && resolveAsyncIterator ( i , i . next ( ) , cb ) ;
88+ return ! data . done && resolveAsyncIterator ( i , i . next ( ) , cb , shouldStop ) ;
9989 } ) ;
10090}
10191
0 commit comments