Skip to content

Instantly share code, notes, and snippets.

@T1mL3arn
Last active October 24, 2023 09:02
Show Gist options
  • Save T1mL3arn/2d153a2447ebfc1c8675f590ae657514 to your computer and use it in GitHub Desktop.
Save T1mL3arn/2d153a2447ebfc1c8675f590ae657514 to your computer and use it in GitHub Desktop.
Simple Future implementation with Haxe language
class Future {
static final PENDING = 1;
static final FULL = 2;
var state:Int = PENDING;
var result:Any = null;
var next:Array<Any->Void> = [];
public function new(){}
public function start(starter:(Any->Void)->Void) {
if (state != FULL) {
starter(completer);
}
return this;
}
function completer(result:Any):Void {
state = FULL;
this.result = result;
for (n in next)
n(this.result);
next = [];
}
public function then(onComplete:Any->Void):Future {
// first attempt to build simple version
if (state == PENDING) {
next.push(onComplete);
} else if (state == FULL){
onComplete(this.result);
}
return this;
}
public function thenf(onComplete:Any->Any):Future {
var f = new Future();
if (state == PENDING) {
next.push(result -> {
var realResult:Any = result;
if (realResult is Future) {
realResult = (cast result:Future).result;
}
var nextResult = onComplete(realResult);
if (nextResult is Future) {
(cast nextResult:Future).thenf(result -> {
f.completer(result);
return result;
});
}
else
f.completer(nextResult);
});
}
else if (state == FULL) {
var nextResult = onComplete(this.result);
if (nextResult is Future)
return nextResult;
else {
var f = new Future();
f.completer(nextResult);
return f;
}
}
return f;
}
}
class Test {
static function main() {
// test it online: https://try.haxe.org/#F69A6783
final wait = (delay:Int, ?id:String) -> {
var stamp = Std.string(Math.fround(Timer.stamp()/1000));
if (id!=null) stamp = id;
trace('[$stamp]: wait for $delay ms...');
return new Future().start(onComplete -> {
Timer.delay(() -> {
trace('[$stamp]: await of $delay ms completed');
onComplete(true);
}, delay);
});
};
wait(1000)
.thenf(_ -> wait(1000))
.thenf(_ -> 42)
.thenf(cast data -> trace('data: $data'))
.thenf(_ -> wait(1000))
.thenf(cast _ -> trace('Futures chain is done!'));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment