所以,我知道在 GWT 中我可以编写纯 JavaScript 代码的 JSNI 代码。但是,不幸的是,如果我在其中使用 ES6 代码,JSNI 代码将无法编译。
这意味着,例如,我不能做这样的事情:
private native void jsniMethod(String jsModule) /*-{
import(jsModule)
.then(loadedModule => {
doStuffWithLoadedModule(loadedModule);
})
.catch(err => alert(err));
}-*/;
Run Code Online (Sandbox Code Playgroud)
有没有办法在 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) });
}-*/;
Run Code Online (Sandbox Code Playgroud)
作为替代方案,要使用 java lambda,您可以使用 JsInterop。请记住,这import实际上不是函数调用,而是 js 关键字,尽管这应该仍然有效:
@JsMethod(namespace = "<window>")
public native Promise<Object> import(String jsModuleName);
Run Code Online (Sandbox Code Playgroud)
然后,您可以调用它并传入 Java lambda:
private void notJsniMethod(String jsModule) {
import(jsModule)
.then(loadedModule -> {
doStuffWithLoadedModule(loadedModule);
return null;
})
.catch_(err -> {
DomGlobal.alert(err.toString())
return null;
});
}
Run Code Online (Sandbox Code Playgroud)
与原来的 JS/JSNI 相比的变化:
=>已替换为 java 的->,其操作方式几乎相同alert(...)现在是DomGlobal.alert(...),因为 java 没有“全局”名称空间return null是必需的,因为 java 不会让您在需要值时“忘记”返回值。.catch(...)替换为.catch_(...), 因为 Java 不允许将关键字用作标识符