This repository was archived by the owner on Apr 20, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
Copy pathasyncsubject.js
111 lines (101 loc) · 3.3 KB
/
asyncsubject.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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* Represents the result of an asynchronous operation.
* The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers.
*/
var AsyncSubject = Rx.AsyncSubject = (function (__super__) {
inherits(AsyncSubject, __super__);
/**
* Creates a subject that can only receive one value and that value is cached for all future observations.
* @constructor
*/
function AsyncSubject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.hasValue = false;
this.observers = [];
this.hasError = false;
}
addProperties(AsyncSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else if (this.hasValue) {
o.onNext(this.value);
o.onCompleted();
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
*/
onCompleted: function () {
var i, len;
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
var os = cloneArray(this.observers), len = os.length;
if (this.hasValue) {
for (i = 0; i < len; i++) {
var o = os[i];
o.onNext(this.value);
o.onCompleted();
}
} else {
for (i = 0; i < len; i++) {
os[i].onCompleted();
}
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the error.
* @param {Mixed} error The Error to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers.
* @param {Mixed} value The value to store in the subject.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
this.hasValue = true;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.error = null;
this.value = null;
}
});
return AsyncSubject;
}(Observable));