-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
48 lines (41 loc) · 1.4 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
function makeBehaviorSubject( initial ) {
let sinks = [];
let last = initial;
return ( type, data ) => {
if ( type === 0 ) {
sinks.push( data );
data( 0, ( t, d ) => {
if ( t === 2 ) {
const i = sinks.indexOf( data );
if ( -1 < i ) {
sinks.splice( i, 1 );
}
}
});
data( 1, last );
}
else {
if ( type === 1 ) {
last = data;
}
// Clone sinks (subscribers) before beginning dispatch to handle the
// case where a dispatched message results in a termination (unsubscribe)
// before all dispatches complete. Without this, mutations of `sinks`
// via the .splice() above were causing indexes out of range as `sinks`
// was iterated.
//
// I considered managing this issue by controlling concurrency (calling
// sinks[i] via a setTimeout( ..., 0 ) so that all notifications are
// dispatched before potential unsubscribes listeners), but I'm concerned
// that may contravene the intent and expectations of users/subscribers.
let subs = sinks.slice( 0 );
for ( let i = 0, n = subs.length; i < n; i++ ) {
// Check that the target subscriber has not been unsubscribed during iteration.
if ( -1 < sinks.indexOf( subs[i] ) ) {
subs[i]( type, data );
}
}
}
}
}
export default makeBehaviorSubject;