Last active
May 13, 2024 09:43
-
-
Save MangelMaxime/e476b6a02021bea2bf7bb47baa79b621 to your computer and use it in GitHub Desktop.
Demonstrate how to use native async/await from JavaScript with haxe.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package async; | |
#if macro | |
import haxe.macro.Context; | |
#end | |
class Async { | |
public static macro function async(expr:haxe.macro.Expr) { | |
expr = Context.storeTypedExpr(Context.typeExpr(expr)); | |
return macro untyped __js__("(async {0})", ${expr})(); | |
} | |
public static macro function await(expr:haxe.macro.Expr) { | |
expr = Context.storeTypedExpr(Context.typeExpr(expr)); | |
return switch (haxe.macro.Context.typeof(expr)) { | |
case TInst(_.toString() => "js.Promise", [t]): | |
var ct = haxe.macro.TypeTools.toComplexType(t); | |
return macro(untyped __js__("await {0}", ${expr}) : $ct); | |
default: | |
throw 'await() is only available for promises'; | |
} | |
} | |
public static macro function asyncPromise(expr:haxe.macro.Expr) { | |
expr = Context.storeTypedExpr(Context.typeExpr(expr)); | |
return macro untyped __js__("(new Promise(async {0}))", ${expr}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package async; | |
@:autoBuild(async.AsyncMacro.macroBuild()) | |
class Asyncify { | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package async; | |
import haxe.macro.Expr; | |
#if macro | |
import haxe.macro.Context; | |
#end | |
class AsyncMacro { | |
public static function macroBuild() { | |
var fields = Context.getBuildFields(); | |
for (field in fields) { | |
function e(expr) return { expr : expr, pos : field.pos }; | |
switch(field.kind) { | |
case FieldType.FFun(f): | |
// trace(field.name); | |
// trace(f.expr); | |
for (m in field.meta) { | |
switch(m.name) { | |
case ":async": | |
var ex = e(EBlock([ | |
e(EReturn( | |
e(EUntyped( | |
e(ECall( | |
e(ECall( | |
e(EConst(CIdent("__js__"))), | |
[ | |
e(EConst(CString("(async {0})"))), | |
e(EFunction(null, | |
{ args : [] | |
, expr : f.expr | |
, params : [] | |
, ret : null | |
} | |
)) | |
] | |
)), | |
[] | |
)) | |
)) | |
)) | |
])); | |
f.expr = ex; | |
default: | |
} | |
} | |
default: | |
} | |
} | |
return fields; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import async.Asyncify; | |
import async.Async; | |
// Here is the ouput generated by the nest program | |
// Start the program | |
// Now #1: 2018-09-05 15:05:03 | |
// Now #2 2018-09-05 15:05:05 | |
// Now #3 2018-09-05 15:05:05 | |
// Now #4 2018-09-05 15:05:07 | |
class Main { | |
static function main() { | |
trace("Start the program"); | |
new Runner().run(); | |
} | |
} | |
// Make your class extends Asyncify to use @:async on a member | |
class Runner extends Asyncify { | |
public function new() { } | |
// By using @:async on a member, it's becoming an async context | |
@:async | |
public function run() { | |
trace("Now #1: " + Date.now().toString()); | |
var now2 = Async.await(resolveAfter2Seconds()); | |
trace("Now #2 " + now2); | |
// We can also create a local async context by using Async.async | |
Async.async(function() { | |
var now4 = Async.await(resolveAfter2Seconds()); | |
trace("Now #4 " + now4); | |
}); | |
trace("Now #3 " + Date.now().toString()); | |
} | |
static function resolveAfter2Seconds() { | |
return new js.Promise(function(resolve, reject) { | |
untyped __js__("setTimeout")(function() { | |
resolve(Date.now().toString()); | |
}, 2000); | |
}); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for the heads up, I missed this one in my research.