Haxe宏 - 将“function”替换为“async function”

4

我希望在将 haxe 转换为 JavaScript 时,能够向其中的方法添加异步操作。

这是我的 Haxe 代码:

@:expose
class Main implements IAsync {    
    static function main() {
        trace("test");
    }       

    static function testAwait() {
        return 1;
    }
}

并且这段代码被转换成了如下的代码:

. . .
Main.testAwait = function() {
    return Main.test();
};
. . .

我希望能够在这段代码中将 function 替换成 async function

例如:

Main.testAwait = async function() {
    return Main.test();
};

但是我只能更改代码宏的方法名称:

package haxe_test;

import haxe.macro.Expr;
import haxe.macro.Context;   
using haxe.macro.Tools;
using haxe_test.AsyncBuilder;

class BuildHub {
    macro static public function build():Array<Field> {
        var fields = Context.getBuildFields();
        var testFunc:Function = {
            expr: macro return $v{1},
            ret: null,
            params: [],
            args: []
        };

    fields.push({
        name:  "testAwait",
        access:  [Access.AStatic],
        kind: FieldType.FFun(testFunc),
        pos: Context.currentPos(),
    });
    return fields;  
}

如何将function替换为async function? 更新:我简化了代码。也许编译器或JSGenApi有什么选项可以帮助我吗?

2
为什么要将异步添加到其方法中?并非所有函数都需要是“async”。或者,您是否想使用“@:async”标记来标记异步函数?我很惊讶Haxe还没有支持async/await-它曾经是一种很好的语言。 - Jaromanda X
2
刚刚发现了这个链接,这个有用吗? - Jaromanda X
1
@JaromandaX,我在示例中简化了代码,但是 这个 不适用,因为我有很多遗留代码 :( - Alex
我认为你可以通过在创建字段时添加元数据,并添加自己的js gen实现来拦截和生成适当的代码,从而实现你想要的功能。 - Christopher Mandlbaur
2个回答

4

如果您希望简化操作,您可以在Haxe 4中使用以下代码:

class Test {
  static function main() {
    var value = await( async(testAsync) );
    trace(value);
  }

  static function testAsync() return 1;

  static inline function await<T>(fn:Void->Void):T {
    return js.Syntax.code("await {0}()", fn);
  }
  static inline function async<T>(fn:Void->Void):T {
      return js.Syntax.code("async () => {0}()", fn);
  }
}

或同时进行两者:

class Test {
  static function main() {
    var value = asyncAwait( testAsync );
    trace(value);
  }

  static function testAsync() return 1;

  static inline function asyncAwait<T>(fn:Void->Void):T {
      return js.Syntax.code("(async () => { await {0}() })()", fn);
  }
}

3

我认为你的一般选择有:

  • 收集构建宏中异步类型/字段的信息,然后在haxe.macro.Context.onAfterGenerate中使用这些信息来修改输出文件。由于Haxe代码是一致缩进的,你可以用几个正则表达式实现(我曾经就是用这种方式编写过一个宏,使其将输出文件按包分割成多个文件)。
  • haxe.macro.ExampleJSGenerator进行略微修改,以在感兴趣的方法声明前添加async。由于不需要对表达式打印做出任何更改,因此这也很容易。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接