8
8
*/
9
9
10
10
export default class EventEmitter < Events : Object > {
11
- listenersMap : Map < string , Set < Function >> = new Map ( ) ;
11
+ listenersMap : Map < string , Array < Function >> = new Map ( ) ;
12
12
13
13
addListener < Event : $Keys < Events >> (
14
14
event : Event ,
15
15
listener : ( ...$ElementType < Events , Event > ) => any ,
16
16
) : void {
17
17
let listeners = this . listenersMap . get ( event ) ;
18
18
if ( listeners === undefined ) {
19
- listeners = new Set ( ) ;
20
-
21
- this . listenersMap . set ( event , listeners ) ;
19
+ this . listenersMap . set ( event , [ listener ] ) ;
20
+ } else {
21
+ const index = listeners . indexOf ( listener ) ;
22
+ if ( index < 0 ) {
23
+ listeners . push ( listener ) ;
24
+ }
22
25
}
23
-
24
- listeners . add ( listener ) ;
25
26
}
26
27
27
28
emit < Event : $Keys < Events >> (
@@ -30,38 +31,45 @@ export default class EventEmitter<Events: Object> {
30
31
) : void {
31
32
const listeners = this . listenersMap . get ( event ) ;
32
33
if ( listeners !== undefined ) {
33
- let didThrow = false ;
34
- let caughtError = null ;
34
+ if ( listeners . length === 1 ) {
35
+ // No need to clone or try/catch
36
+ const listener = listeners [ 0 ] ;
37
+ listener . apply ( null , args ) ;
38
+ } else {
39
+ let didThrow = false ;
40
+ let caughtError = null ;
35
41
36
- listeners . forEach ( listener => {
37
- try {
38
- listener . apply ( null , args ) ;
39
- } catch ( error ) {
40
- if ( caughtError === null ) {
41
- didThrow = true ;
42
- caughtError = error ;
42
+ const clonedListeners = Array . from ( listeners ) ;
43
+ for ( let i = 0 ; i < clonedListeners . length ; i ++ ) {
44
+ const listener = clonedListeners [ i ] ;
45
+ try {
46
+ listener . apply ( null , args ) ;
47
+ } catch ( error ) {
48
+ if ( caughtError === null ) {
49
+ didThrow = true ;
50
+ caughtError = error ;
51
+ }
43
52
}
44
53
}
45
- } ) ;
46
54
47
- if ( didThrow ) {
48
- throw caughtError ;
55
+ if ( didThrow ) {
56
+ throw caughtError ;
57
+ }
49
58
}
50
59
}
51
60
}
52
61
53
- removeAllListeners ( event ?: $Keys < Events > ): void {
54
- if ( event != null ) {
55
- this . listenersMap . delete ( event ) ;
56
- } else {
57
- this . listenersMap . clear ( ) ;
58
- }
62
+ removeAllListeners ( ) : void {
63
+ this . listenersMap . clear ( ) ;
59
64
}
60
65
61
66
removeListener ( event : $Keys < Events > , listener : Function ) : void {
62
67
const listeners = this . listenersMap . get ( event ) ;
63
68
if ( listeners !== undefined ) {
64
- listeners . delete ( listener ) ;
69
+ const index = listeners . indexOf ( listener ) ;
70
+ if ( index >= 0 ) {
71
+ listeners . splice ( index , 1 ) ;
72
+ }
65
73
}
66
74
}
67
75
}
0 commit comments