代码之家  ›  专栏  ›  技术社区  ›  Yuriy Hladyuk

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

  •  2
  • Yuriy Hladyuk  · 技术社区  · 7 年前

    是否可以从基于kotlin JVM的项目中调用javascript函数? 例如,我得到了一门课:

    class JS{
    
     fun callJS( ){
      // somehow call js function
     }
    }
    
    1 回复  |  直到 7 年前
        1
  •  4
  •   Zoe - Save the data dump 张群峰    7 年前

    可以使用带有JavaScript的ScriptEngineManager作为引擎。

    您可以使用ScriptEngineManager。getEngineByName来获取引擎本身,但这不允许从Java调用方法。为此,您需要一个Invocable。这是由first完成的 eval 对脚本进行赋值(作为读取器或字符串),然后将其转换为可调用脚本。

    我个人更喜欢使用两个扩展函数。您不需要两者兼用,但有一个用于读卡器,另一个用于字符串:

    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
    }
    

    这里的引擎是JavaScript引擎,它使用它来评估代码中的字符串或代码中的文件读取器。这真的取决于你如何储存它。

    然后使用Invocable调用函数。

    请注意,如果函数没有返回任何内容,它将返回null,否则它将给出一个非null对象。当然,这假设没有返回null。

    无论如何,对于实际的发动机。ScriptEngineManager位于javax包中,因此您不需要添加任何依赖项或库来使用它。您需要一个ScriptEngineManager来获取引擎本身:

    val engineManager = ScriptEngineManager()
    

    ScriptEngineManager只是引擎的管理者。它不能直接用于评估,因为它不是引擎。由于需要JavaScript引擎,因此可以调用 getEngineByName ,并通过 javascript :

    val engine = engineManager.getEngineByName("javascript")
    

    这就是扩展函数的用武之地。创建一个新的读取器(如果愿意,也可以将字符串与源一起使用),并调用createInvocable:

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

    最后,调用函数:

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

    如果您有返回值,请添加一个var或val来捕获它。