-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfutures.js
92 lines (84 loc) · 2.33 KB
/
futures.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
function arrayify(args) {
return Array.prototype.slice.apply(args);
}
function extend(subClass, baseClass) {
function inheritance() { }
inheritance.prototype = baseClass.prototype;
subClass.prototype = new inheritance();
subClass.prototype.constructor = subClass;
subClass.prototype.superClass = baseClass.prototype;
};
var unfulfilledFutures = [];
function Future() {
unfulfilledFutures.push(this);
this.continuations_ = [];
}
Future.prototype.fulfill = function() {
if (this.isFulfilled())
throw new Error('Future is already fulfilled');
var result = arrayify(arguments);
this.result_ = result;
this.continuations_.forEach(function(cont) {
cont.apply(null, result);
});
unfulfilledFutures.splice(unfulfilledFutures.indexOf(this), 1);
if (unfulfilledFutures.length == 0)
console.log("No unfulfilled futures left");
this.continuations_ = [];
};
Future.prototype.then = function(continuation) {
var args = this.result_;
if (args) {
continuation.apply(null, args);
} else {
this.continuations_.push(continuation);
}
return this;
};
Future.prototype.pipe = function(future) {
this.then(function() {
future.fulfill.apply(future, arguments);
});
};
Future.prototype.defer = function(f) {
var future = new Future();
this.then(function() {
f.apply(null, arguments).pipe(future);
});
return future;
};
Future.prototype.isFulfilled = function() {
return (typeof this.result_ != 'undefined');
};
function ImmediateFuture() {
this.superClass.constructor.call(this);
this.fulfill.apply(this, arguments);
}
extend(ImmediateFuture, Future);
function TimedFuture(timeout) {
this.superClass.constructor.call(this);
window.setTimeout(this.fulfill.bind(this), timeout);
}
extend(TimedFuture, Future);
var requestAnimationFrame_ = window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame;
function AnimationFuture() {
this.superClass.constructor.call(this);
requestAnimationFrame_(this.fulfill.bind(this));
}
extend(AnimationFuture, Future);
function repeat_until(body, condition) {
var f = new Future();
loop();
function loop() {
body().then(function() {
if (condition()) {
f.fulfill();
} else {
loop();
}
});
}
return f;
}