@@ -67,51 +67,47 @@ const actualMiddlewarePhases = ['beforeReducer', 'afterReducer'] as const
67
67
68
68
function createTakePattern < S > (
69
69
addListener : AddListenerOverloads < Unsubscribe , S , Dispatch < AnyAction > > ,
70
- parentJob ? : Job < any >
70
+ parentJob : Job < any >
71
71
) : TakePattern < S > {
72
72
async function take < P extends AnyActionListenerPredicate < S > > (
73
73
predicate : P ,
74
74
timeout : number | undefined
75
75
) {
76
76
let unsubscribe : Unsubscribe = ( ) => { }
77
- let job : JobHandle
78
-
79
- // TODO Need to figure out how to propagate cancelations of the job that
80
- // is locked inside of the middleware back up into here, so that a canceled
81
- // listener waiting on a condition has that condition throw instead.
82
- // Maybe rewrite these around use of `Job.pause()` instead?
83
-
84
- const tuplePromise = new Promise < [ AnyAction , S , S ] > ( ( resolve ) => {
77
+ let job : Job < [ AnyAction , S , S ] > = parentJob . launch ( async ( job ) => Outcome . wrap ( new Promise < [ AnyAction , S , S ] > ( ( resolve ) => {
85
78
unsubscribe = addListener ( {
86
79
predicate : predicate as any ,
87
80
listener : ( action , listenerApi ) : void => {
88
81
// One-shot listener that cleans up as soon as the predicate resolves
89
82
listenerApi . unsubscribe ( )
90
- resolve ( [
83
+ resolve ( ( [
91
84
action ,
92
85
listenerApi . getState ( ) ,
93
86
listenerApi . getOriginalState ( ) ,
94
- ] )
87
+ ] ) )
95
88
} ,
96
89
parentJob,
97
90
} )
98
- } )
91
+ } ) ) ) ;
99
92
100
- let promises : Promise < unknown > [ ] = [ tuplePromise ]
101
93
102
- if ( timeout !== undefined ) {
103
- const timedOutPromise = new Promise < null > ( ( resolve , reject ) => {
104
- setTimeout ( ( ) => {
105
- resolve ( null )
106
- } , timeout )
107
- } )
108
- promises = [ tuplePromise , timedOutPromise ]
109
- }
94
+ let result : Outcome < [ AnyAction , S , S ] > ;
95
+
96
+ try {
97
+ result = await ( timeout !== undefined ? job . runWithTimeout ( timeout ) : job . run ( ) ) ;
98
+
99
+ if ( result . isOk ( ) ) {
100
+ return result . value ;
101
+ } else if ( result . error instanceof JobCancellationException ) {
102
+ return false ;
103
+ }
110
104
111
- const result = await Promise . race ( promises )
105
+ throw result . error ;
106
+
107
+ } finally {
108
+ unsubscribe ( )
109
+ }
112
110
113
- unsubscribe ( )
114
- return result
115
111
}
116
112
117
113
return take as TakePattern < S >
@@ -310,11 +306,6 @@ export function createActionListenerMiddleware<
310
306
return true
311
307
}
312
308
313
- const take = createTakePattern ( addListener )
314
- const condition : ConditionFunction < S > = ( predicate , timeout ) => {
315
- return take ( predicate , timeout ) . then ( Boolean )
316
- }
317
-
318
309
const middleware : Middleware <
319
310
{
320
311
( action : Action < 'actionListenerMiddleware/add' > ) : Unsubscribe
@@ -372,6 +363,11 @@ export function createActionListenerMiddleware<
372
363
}
373
364
374
365
entry . parentJob . launchAndRun ( async ( jobHandle ) => {
366
+ const take = createTakePattern ( addListener , entry . parentJob as Job < any > ) ;
367
+ const condition : ConditionFunction < S > = ( predicate , timeout ) => {
368
+ return take ( predicate , timeout ) . then ( Boolean )
369
+ }
370
+
375
371
const result = await Outcome . try ( async ( ) =>
376
372
entry . listener ( action , {
377
373
...api ,
0 commit comments