简体   繁体   English

从基于Kotlin JVM的项目中调用javascript函数

[英]Call javascript function from kotlin JVM based project

Is is possible to call javascript functions from kotlin JVM based project? 是否可以从基于kotlin JVM的项目中调用javascript函数? Like for example I got class: 例如,我上课了:

class JS{

 fun callJS( ){
  // somehow call js function
 }
}

You can use a ScriptEngineManager with JavaScript as the engine. 您可以使用带有JavaScript的ScriptEngineManager作为引擎。

You use ScriptEngineManager.getEngineByName to get the engine itself, but that doesn't allow calling methods from Java. 您可以使用ScriptEngineManager.getEngineByName来获取引擎本身,但是不允许从Java调用方法。 In order to do this, you need an Invocable. 为此,您需要一个Invocable。 This is done by first eval uating the script (either as a Reader or String) and then casting it as an Invocable. 首先eval脚本(作为阅读器或字符串),然后将其强制转换为可调用对象。

I personally prefer using two extension functions for this. 我个人更喜欢为此使用两个扩展功能。 You don't need both, but there's one for Readers and one for Strings: 两者都不需要,但是Readers和Strings都有:

fun String.createInvocable(engine: ScriptEngine) : Invocable {
    engine.eval(this);
    return engine as Invocable;
}

fun Reader.createInvocable(engine: ScriptEngine) : Invocable{
    engine.eval(this)
    return engine as Invocable
}

The engine here is the JavaScript engine, and it uses it to eval the either String with the code or reader to the file with the code. 这里的引擎是JavaScript引擎,它使用它来评估带有代码的String或带有代码的文件阅读器。 It really depends on how you store it. 这实际上取决于您如何存储它。

And then you use the Invocable to call the function. 然后使用Invocable调用该函数。

Note that it returns null if there's nothing returned from the function, otherwise it gives a non-null object. 请注意,如果函数未返回任何内容,则返回null;否则,它给出一个非null的对象。 That assumes null isn't being returned of course. 假定当然不返回null。

Anyways, for the actual engine. 无论如何,对于实际的引擎。 ScriptEngineManager is in the javax package, so you don't need to add any dependencies or libraries to use it. ScriptEngineManager在javax软件包中,因此您无需添加任何依赖项或库即可使用它。 You need a ScriptEngineManager in order to get the engine itself: 您需要一个ScriptEngineManager来获取引擎本身:

val engineManager = ScriptEngineManager()

The ScriptEngineManager is just a manager of the engines. ScriptEngineManager只是引擎的管理器。 It can't be used directly for evaluating, since it isn't the engine. 由于它不是引擎,因此不能直接用于评估。 Since you want the JavaScript engine, you call getEngineByName , and pass javascript : 由于您需要JavaScript引擎,因此可以调用getEngineByName并传递javascript

val engine = engineManager.getEngineByName("javascript")

And this is where the extension functions come in. Create a new Reader (or use the String with the source if you prefer) and call createInvocable: 这就是扩展功能的所在。创建一个新的Reader(或者,如果愿意,可以将String与源一起使用)并调用createInvocable:

val invocable = Files.newBufferedReader(Paths.get("dir")).createInvocable(engine)

And finally, call the function: 最后,调用函数:

invocable.invokeFunction("name", "arguments")//there can be no arguments

If you have return values, add a var, or val to catch it. 如果您有返回值,请添加一个var或val来捕获它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM