如何使用从 GWT jsni 代码导入的 ECMAScript-6?

How to use ECMAScript-6 import from a GWT jsni code?

所以,我知道在 GWT 中我可以编写纯 javascript 代码的 JSNI 代码。 但是,不幸的是,如果我在其中使用 ES6 代码,则 JSNI 代码无法编译。

这意味着,例如,我不能做这样的事情:

private native void jsniMethod(String jsModule) /*-{
    import(jsModule)
        .then(loadedModule => {
            doStuffWithLoadedModule(loadedModule);
        })
        .catch(err => alert(err));
}-*/;

有没有办法在 GWT 代码中实现这一点? 我的意思是,我需要一个 loadedModule 的引用,这样我就可以在一些 jsni 代码中使用它(doStuffWithLoadedModule 方法实现)。

谢谢!

这是不可能的。您需要将 JSNI 不支持的 JS 特性放入某种外部 JS 中,或者在与 JSNI 兼容的旧 JS 中重写它们。考虑将 ScriptInjector 作为一个选项,或者您的主机 html 页面。

对于这个具体的事情,你只需要用函数替换箭头运算符:

private native void jsniMethod(String jsModule) /*-{
    import(jsModule)
        .then(function(loadedModule) {
            doStuffWithLoadedModule(loadedModule);
        })
        .catch(function(err) { alert(err) });
}-*/;

作为替代方案,要使用 java lambda,您可以使用 JsInterop。请记住 import 实际上不是一个函数调用,而是一个 js 关键字,尽管这应该仍然有效:

@JsMethod(namespace = "<window>")
public native Promise<Object> import(String jsModuleName);

然后,您可以调用它并传入 Java lambdas:

private void notJsniMethod(String jsModule) {
    import(jsModule)
        .then(loadedModule -> {
            doStuffWithLoadedModule(loadedModule);
            return null;
        })
        .catch_(err -> {
            DomGlobal.alert(err.toString())
            return null;
        });

}

从原来的变化JS/JSNI:

  • => 替换为 java 的 ->,其操作方式几乎相同
  • alert(...) 现在是 DomGlobal.alert(...),因为 java 没有 "global" 命名空间
  • 显式 return null 是必需的,因为 java 不允许您在需要值时仅 "forget" 到 return 一个值。
  • .catch(...) 替换为 .catch_(...),因为 Java 不允许将关键字用作标识符