@@ -783,6 +783,64 @@ class Generator extends EventEmitter {
783
783
} ) ;
784
784
}
785
785
786
+ /**
787
+ * @private
788
+ * Schedule a generator's method on a run queue.
789
+ *
790
+ * @param {String } name: The method name to schedule.
791
+ * @param {TaskOptions } [taskOptions]: options.
792
+ */
793
+ queueOwnTask ( name , taskOptions = { } ) {
794
+ const property = Object . getOwnPropertyDescriptor ( Object . getPrototypeOf ( this ) , name ) ;
795
+ const item = property . value ? property . value : property . get . call ( this ) ;
796
+
797
+ const priority = this . _queues [ name ] ;
798
+ taskOptions = {
799
+ ...priority ,
800
+ cancellable : true ,
801
+ run : false ,
802
+ ...taskOptions
803
+ } ;
804
+
805
+ // Name points to a function; run it!
806
+ if ( typeof item === 'function' ) {
807
+ taskOptions . taskName = name ;
808
+ taskOptions . method = item ;
809
+ this . queueTask ( taskOptions ) ;
810
+ return ;
811
+ }
812
+
813
+ // Not a queue hash; stop
814
+ if ( ! priority ) {
815
+ return ;
816
+ }
817
+
818
+ this . queueTaskGroup ( item , taskOptions ) ;
819
+ }
820
+
821
+ /**
822
+ * @private
823
+ * Schedule every generator's methods on a run queue.
824
+ *
825
+ * @param {TaskOptions } [taskOptions]: options.
826
+ */
827
+ queueOwnTasks ( taskOptions ) {
828
+ this . _running = true ;
829
+ this . _taskStatus = { cancelled : false , timestamp : new Date ( ) } ;
830
+
831
+ const methods = Object . getOwnPropertyNames ( Object . getPrototypeOf ( this ) ) ;
832
+ const validMethods = methods . filter ( methodIsValid ) ;
833
+ if ( ! validMethods . length ) {
834
+ const error = new Error (
835
+ 'This Generator is empty. Add at least one method for it to run.'
836
+ ) ;
837
+ this . emit ( 'error' , error ) ;
838
+ throw error ;
839
+ }
840
+
841
+ validMethods . forEach ( methodName => this . queueOwnTask ( methodName , taskOptions ) ) ;
842
+ }
843
+
786
844
/**
787
845
* Schedule tasks on a run queue.
788
846
*
@@ -810,6 +868,7 @@ class Generator extends EventEmitter {
810
868
namespace = self . options . namespace ;
811
869
}
812
870
871
+ const taskStatus = this . _taskStatus ;
813
872
debug (
814
873
`Queueing ${ namespace } #${ methodName } with options %o` ,
815
874
_ . omit ( task , [ 'method' ] )
@@ -820,23 +879,18 @@ class Generator extends EventEmitter {
820
879
continueQueue => {
821
880
debug ( `Running ${ namespace } #${ methodName } ` ) ;
822
881
self . emit ( `method:${ methodName } ` ) ;
823
- const taskCancelled = task . cancellable && ! self . _running ;
882
+ const taskCancelled = task . cancellable && taskStatus . cancelled ;
883
+ if ( taskCancelled ) {
884
+ continueQueue ( ) ;
885
+ return ;
886
+ }
824
887
825
888
runAsync ( function ( ) {
826
- if ( taskCancelled ) {
827
- return Promise . resolve ( ) ;
828
- }
829
-
830
889
self . async = ( ) => this . async ( ) ;
831
890
self . runningState = { namespace, queueName, methodName } ;
832
891
return method . apply ( self , self . args ) ;
833
892
} ) ( )
834
893
. then ( function ( ) {
835
- if ( taskCancelled ) {
836
- continueQueue ( ) ;
837
- return ;
838
- }
839
-
840
894
delete self . runningState ;
841
895
const eventName = `done$${ namespace || 'unknownnamespace' } #${ methodName } ` ;
842
896
debug ( `Emiting event ${ eventName } ` ) ;
@@ -878,6 +932,19 @@ class Generator extends EventEmitter {
878
932
*/
879
933
cancelCancellableTasks ( ) {
880
934
this . _running = false ;
935
+ this . _taskStatus . cancelled = true ;
936
+ delete this . _taskStatus ;
937
+ }
938
+
939
+ /**
940
+ * Start the generator again.
941
+ *
942
+ * @param {Object } [options]: options.
943
+ */
944
+ startOver ( options = { } ) {
945
+ this . cancelCancellableTasks ( ) ;
946
+ Object . assign ( this . options , options ) ;
947
+ this . queueOwnTasks ( ) ;
881
948
}
882
949
883
950
/**
@@ -933,8 +1000,6 @@ class Generator extends EventEmitter {
933
1000
}
934
1001
935
1002
const promise = new Promise ( ( resolve , reject ) => {
936
- const self = this ;
937
- this . _running = true ;
938
1003
this . debug ( 'Generator is starting' ) ;
939
1004
this . emit ( 'run' ) ;
940
1005
@@ -948,52 +1013,15 @@ class Generator extends EventEmitter {
948
1013
this . on ( 'error' , reject ) ;
949
1014
}
950
1015
951
- const methods = Object . getOwnPropertyNames ( Object . getPrototypeOf ( this ) ) ;
952
- const validMethods = methods . filter ( methodIsValid ) ;
953
- if ( ! validMethods . length ) {
954
- return this . emit (
955
- 'error' ,
956
- new Error ( 'This Generator is empty. Add at least one method for it to run.' )
957
- ) ;
958
- }
959
-
960
1016
this . env . runLoop . once ( 'end' , ( ) => {
961
1017
this . debug ( 'Generator has ended' ) ;
962
1018
this . emit ( 'end' ) ;
963
1019
resolve ( ) ;
964
1020
} ) ;
965
1021
966
- function addInQueue ( name ) {
967
- const property = Object . getOwnPropertyDescriptor (
968
- Object . getPrototypeOf ( self ) ,
969
- name
970
- ) ;
971
- const item = property . value ? property . value : property . get . call ( self ) ;
972
-
973
- const priority = self . _queues [ name ] ;
974
- let taskOptions = {
975
- ...priority ,
976
- cancellable : true ,
977
- run : false ,
978
- generatorReject : usePromise ? undefined : reject
979
- } ;
980
-
981
- // Name points to a function; run it!
982
- if ( typeof item === 'function' ) {
983
- taskOptions . taskName = name ;
984
- taskOptions . method = item ;
985
- return self . queueTask ( taskOptions ) ;
986
- }
987
-
988
- // Not a queue hash; stop
989
- if ( ! priority ) {
990
- return ;
991
- }
992
-
993
- self . queueTaskGroup ( item , taskOptions ) ;
994
- }
995
-
996
- validMethods . forEach ( addInQueue ) ;
1022
+ this . queueOwnTasks ( {
1023
+ generatorReject : usePromise ? undefined : reject
1024
+ } ) ;
997
1025
998
1026
const writeFiles = ( ) => {
999
1027
this . env . runLoop . add ( 'conflicts' , this . _writeFiles . bind ( this ) , {
@@ -1016,6 +1044,7 @@ class Generator extends EventEmitter {
1016
1044
} ) ;
1017
1045
1018
1046
this . _composedWith . forEach ( runGenerator ) ;
1047
+ this . _composedWith = [ ] ;
1019
1048
} ) ;
1020
1049
1021
1050
// For composed generators, otherwise error will not be catched.
0 commit comments