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); | |
}); | |
} | |
} | |
Thank you for all the changes, I will take a look at them later on.
I also discovered that someone made a library for exploiting native Javascript promise with Haxe 4: https://github.com/basro/hx-jsasync
I didn't have time to test it yet.
Thanks for the heads up, I missed this one in my research.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This gist is the first Google result for "haxe async await" and is still relevant, so minor 2020 fixes:
To remove the legacy warnings for untyped js (now it's supposed to be js.Syntax.code() instead), replace the expression macro block with
Same thing in other places:
And, as a minor convenience, you can do this:
To use this: