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 pathtimeout.js
127 lines (112 loc) · 3.93 KB
/
timeout.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
var TimeoutError = Rx.TimeoutError = function(message) {
this.message = message || 'Timeout has occurred';
this.name = 'TimeoutError';
Error.call(this);
};
TimeoutError.prototype = Object.create(Error.prototype);
function timeoutWithSelector(source, firstTimeout, timeoutDurationSelector, other) {
if (isFunction(firstTimeout)) {
other = timeoutDurationSelector;
timeoutDurationSelector = firstTimeout;
firstTimeout = observableNever();
}
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var subscription = new SerialDisposable(),
timer = new SerialDisposable(),
original = new SingleAssignmentDisposable();
subscription.setDisposable(original);
var id = 0, switched = false;
function setTimer(timeout) {
var myId = id, d = new SingleAssignmentDisposable();
function timerWins() {
switched = (myId === id);
return switched;
}
timer.setDisposable(d);
d.setDisposable(timeout.subscribe(function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
d.dispose();
}, function (e) {
timerWins() && o.onError(e);
}, function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
}));
};
setTimer(firstTimeout);
function oWins() {
var res = !switched;
if (res) { id++; }
return res;
}
original.setDisposable(source.subscribe(function (x) {
if (oWins()) {
o.onNext(x);
var timeout = tryCatch(timeoutDurationSelector)(x);
if (timeout === errorObj) { return o.onError(timeout.e); }
setTimer(isPromise(timeout) ? observableFromPromise(timeout) : timeout);
}
}, function (e) {
oWins() && o.onError(e);
}, function () {
oWins() && o.onCompleted();
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
function timeout(source, dueTime, other, scheduler) {
if (isScheduler(other)) {
scheduler = other;
other = observableThrow(new TimeoutError());
}
if (other instanceof Error) { other = observableThrow(other); }
isScheduler(scheduler) || (scheduler = defaultScheduler);
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var id = 0,
original = new SingleAssignmentDisposable(),
subscription = new SerialDisposable(),
switched = false,
timer = new SerialDisposable();
subscription.setDisposable(original);
function createTimer() {
var myId = id;
timer.setDisposable(scheduler.scheduleFuture(null, dueTime, function () {
switched = id === myId;
if (switched) {
isPromise(other) && (other = observableFromPromise(other));
subscription.setDisposable(other.subscribe(o));
}
}));
}
createTimer();
original.setDisposable(source.subscribe(function (x) {
if (!switched) {
id++;
o.onNext(x);
createTimer();
}
}, function (e) {
if (!switched) {
id++;
o.onError(e);
}
}, function () {
if (!switched) {
id++;
o.onCompleted();
}
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
observableProto.timeout = function () {
var firstArg = arguments[0];
if (firstArg instanceof Date || typeof firstArg === 'number') {
return timeout(this, firstArg, arguments[1], arguments[2]);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return timeoutWithSelector(this, firstArg, arguments[1], arguments[2]);
} else {
throw new Error('Invalid arguments');
}
};