@@ -22,18 +22,41 @@ function allPromises<U = unknown>(collection: Array<U | PromiseLike<U>>): Promis
22
22
} ) ;
23
23
}
24
24
25
- /** A simple queue that holds promises. */
26
- export class PromiseBuffer < T > {
27
- /** Internal set of queued Promises */
28
- private readonly _buffer : Array < PromiseLike < T > > = [ ] ;
25
+ export interface PromiseBuffer < T > {
26
+ _buffer : Array < PromiseLike < T > > ;
27
+ isReady ( ) : boolean ;
28
+ add ( taskProducer : ( ) => PromiseLike < T > ) : PromiseLike < T > ;
29
+ remove ( task : PromiseLike < T > ) : PromiseLike < T > ;
30
+ length ( ) : number ;
31
+ drain ( timeout ?: number ) : PromiseLike < boolean > ;
32
+ }
33
+
34
+ /**
35
+ * Creates an new PromiseBuffer object with the specified limit
36
+ * @param limit max number of promises that can be stored in the buffer
37
+ */
38
+ export function makePromiseBuffer < T > ( limit ?: number ) : PromiseBuffer < T > {
39
+ const buffer : Array < PromiseLike < T > > = [ ] ;
40
+
41
+ /**
42
+ * This function returns the number of unresolved promises in the queue.
43
+ */
44
+ function length ( ) : number {
45
+ return buffer . length ;
46
+ }
29
47
30
- public constructor ( protected _limit ?: number ) { }
48
+ function isReady ( ) : boolean {
49
+ return limit === undefined || length ( ) < limit ;
50
+ }
31
51
32
52
/**
33
- * Says if the buffer is ready to take more requests
53
+ * Remove a promise from the queue.
54
+ *
55
+ * @param task Can be any PromiseLike<T>
56
+ * @returns Removed promise.
34
57
*/
35
- public isReady ( ) : boolean {
36
- return this . _limit === undefined || this . length ( ) < this . _limit ;
58
+ function remove ( task : PromiseLike < T > ) : PromiseLike < T > {
59
+ return buffer . splice ( buffer . indexOf ( task ) , 1 ) [ 0 ] ;
37
60
}
38
61
39
62
/**
@@ -46,47 +69,29 @@ export class PromiseBuffer<T> {
46
69
* limit check.
47
70
* @returns The original promise.
48
71
*/
49
- public add ( taskProducer : ( ) => PromiseLike < T > ) : PromiseLike < T > {
50
- if ( ! this . isReady ( ) ) {
72
+ function add ( taskProducer : ( ) => PromiseLike < T > ) : PromiseLike < T > {
73
+ if ( ! isReady ( ) ) {
51
74
return SyncPromise . reject ( new SentryError ( 'Not adding Promise due to buffer limit reached.' ) ) ;
52
75
}
53
76
54
77
// start the task and add its promise to the queue
55
78
const task = taskProducer ( ) ;
56
- if ( this . _buffer . indexOf ( task ) === - 1 ) {
57
- this . _buffer . push ( task ) ;
79
+ if ( buffer . indexOf ( task ) === - 1 ) {
80
+ buffer . push ( task ) ;
58
81
}
59
82
void task
60
- . then ( ( ) => this . remove ( task ) )
83
+ . then ( ( ) => remove ( task ) )
61
84
// Use `then(null, rejectionHandler)` rather than `catch(rejectionHandler)` so that we can use `PromiseLike`
62
85
// rather than `Promise`. `PromiseLike` doesn't have a `.catch` method, making its polyfill smaller. (ES5 didn't
63
86
// have promises, so TS has to polyfill when down-compiling.)
64
87
. then ( null , ( ) =>
65
- this . remove ( task ) . then ( null , ( ) => {
66
- // We have to add another catch here because `this. remove()` starts a new promise chain.
88
+ remove ( task ) . then ( null , ( ) => {
89
+ // We have to add another catch here because `remove()` starts a new promise chain.
67
90
} ) ,
68
91
) ;
69
92
return task ;
70
93
}
71
94
72
- /**
73
- * Remove a promise from the queue.
74
- *
75
- * @param task Can be any PromiseLike<T>
76
- * @returns Removed promise.
77
- */
78
- public remove ( task : PromiseLike < T > ) : PromiseLike < T > {
79
- const removedTask = this . _buffer . splice ( this . _buffer . indexOf ( task ) , 1 ) [ 0 ] ;
80
- return removedTask ;
81
- }
82
-
83
- /**
84
- * This function returns the number of unresolved promises in the queue.
85
- */
86
- public length ( ) : number {
87
- return this . _buffer . length ;
88
- }
89
-
90
95
/**
91
96
* Wait for all promises in the queue to resolve or for timeout to expire, whichever comes first.
92
97
*
@@ -96,7 +101,7 @@ export class PromiseBuffer<T> {
96
101
* @returns A promise which will resolve to `true` if the queue is already empty or drains before the timeout, and
97
102
* `false` otherwise
98
103
*/
99
- public drain ( timeout ?: number ) : PromiseLike < boolean > {
104
+ function drain ( timeout ?: number ) : PromiseLike < boolean > {
100
105
return new SyncPromise < boolean > ( resolve => {
101
106
// wait for `timeout` ms and then resolve to `false` (if not cancelled first)
102
107
const capturedSetTimeout = setTimeout ( ( ) => {
@@ -106,10 +111,21 @@ export class PromiseBuffer<T> {
106
111
} , timeout ) ;
107
112
108
113
// if all promises resolve in time, cancel the timer and resolve to `true`
109
- void allPromises ( this . _buffer ) . then ( ( ) => {
114
+ void allPromises ( buffer ) . then ( ( ) => {
110
115
clearTimeout ( capturedSetTimeout ) ;
111
116
resolve ( true ) ;
112
117
} ) ;
113
118
} ) ;
114
119
}
120
+
121
+ const promiseBuffer : PromiseBuffer < T > = {
122
+ _buffer : buffer ,
123
+ length,
124
+ isReady,
125
+ add,
126
+ remove,
127
+ drain,
128
+ } ;
129
+
130
+ return promiseBuffer ;
115
131
}
0 commit comments