当前位置: 首页 > 面试题库 >

用Rhino解析Java中的JavaScript:暂停/恢复脚本

韩欣怿
2023-03-14
问题内容

我正在使用JDK的javax.script。*包。具体来说,我使用的是JavaScript引擎,据我所读,它似乎是基于Mozilla开发的名为Rhino的JavaScript-
in-Java解释器。

我希望完成的工作基本上是使我的JavaScript能够在代码中的某个点“暂停”自身(例如,在函数调用的一半),并且只有在Java允许的情况下稍后才能自我恢复。

为了说明我的意思,请想象以下JavaScript代码:

function myJSFunction() {
    print("Hello ");
    mysteriousPauseFunction(); // this is the part I'm wondering about.  basically, the script should break here and resume later at Java's discretion...
    // upon reaching this comment, we know now that Java has told JavaScript that it's okay to resume, so the next line will now be executed...
    print("world");
}

如果“暂停”
/“中断”部分涉及绑定Java函数并将其引用传递给当前ScriptEngine或其他东西,那对我来说很酷。我认为这可能涉及:从Java内部暂停JavaScript。

我进行了一次谷歌搜索,发现这里的关键字似乎是“
continuations”。据我所知,Rhino仅支持解释模式下的延续(相对于编译模式),我认为这是通过将“上下文”设置为-2来实现的。既然内置的JDK
ScriptEngine似乎没有提到任何有关上下文的内容(或者我可能错过了),这是否意味着我必须直接下载并使用Mozilla的Rhino库?

我需要Rhino延续吗?我已经找到了有关Rhino延续的有用教程,但是在阅读完该教程之后,我不确定100%是否能够实现我上面描述的内容。如果这
我要查找的内容,那么我的后续问题是有关提到的“序列化”的问题:这是否意味着当我继续执行脚本时,除非对它们进行序列化,否则所有变量都将未设置?

更新: Rhino似乎可以做到这一点。到目前为止,这是我在JavaScript中拥有的东西;在代码之后,我将解释它的作用…

var end = new Continuation();

function myJSFunction()
{
    print("Hello ");
    var kont = new Continuation();
    storePause(script, kont); // script is previously bound by Java into the JavaScript.  it is a reference to the script itself.
    end();
    print("world");

}

我的“
storePause()”函数是我编写的Java函数,并且已绑定到JavaScript,但是现在,它什么也没做。我的下一个目标是充实其代码,以便将延续和脚本信息存储为Java对象,以便Java可以在以后恢复脚本。

现在,它的作用是在打印“ Hello”之后但在打印“ world”之前暂停/“破坏”脚本,因此向我证明了可以以这种方式暂停脚本。

因此,我现在只需要弄清楚的是如何恢复延续。请注意,以上默认情况下使用JDK脚本引擎工作(此时我不需要担心解释模式还是编译模式-
似乎默认为解释模式),但是它看起来像恢复脚本的过程将需要Mozilla的Rhino库。


问题答案:

好吧,这花了我很多时间来研究文档,教程和示例,并在这里和Rhino Google
Group上发布
,但我设法编写了一个可行的解决方案。由于似乎没有完整的示例,因此我将在此发布我的发现,以供将来偶然发现此问题的任何人使用。

实际上,我的发现可能太长了,无法在此处发布,因此我决定在我的博客上写一个教程:

http://www.joshforde.com/blog/?p=7

希望能对某人有所帮助。据我所知,这是唯一完整的Rhino教程,显示了如何执行以下所有操作:初始化Rhino,从JavaScript(*
.js)文件加载脚本,自动绑定特定Java类中的所有函数(例如ScriptFunctions)作为JavaScript中的全局函数,最后调用JavaScript函数并处理该调用的延续。

基本上 ,问题是我需要先下载Mozilla
Rhino源代码(因为JDK附带的版本已过时并且不支持延续),重写我的所有代码以使用官方Rhino软件包的语法(这非常与JDK的ScriptingEngine语法不同),编写一个抛出ContinuationPending异常并将其绑定到JavaScript的Java函数,以便JavaScript可以对其进行调用(因为直接从JavaScript抛出ContinuationPending会导致抛出JavaScriptException,而不是抛出ContinuationPending,甚至尝试在该JavaScriptException上调用getCause()结果为null),然后在调用我的JavaScript函数(在我的原始示例中为“
myJSFunction”)的Java代码中,使用try / catch块来检查ContinuationPending(这是一个例外)
,然后再使用该ContinuationPending继续执行脚本。

ew 这很艰难,但是现在都值得。



 类似资料:
  • 问题内容: 我有一个基本的Swing UI,带有一个标记为“播放”的按钮。按下按钮后,标签变为“暂停”。现在,当按下按钮时,它变为“继续”。 在“播放”中,我将实例化并执行一个SwingWorker。我想要的是能够暂停该线程(不要取消该线程),并根据上述按钮按下来恢复它。但是,我不想在doInBackground()中求助于Thread.sleep()。这似乎有点骇人听闻。有什么方法可以阻止运行d

  • 我要做的是暂停< code>KafkaConsumer,如果在使用消息的过程中出现错误。 这是我写的 然后我写了一个REST服务来恢复消费者 现在,我有两个问题。第一个问题:当我打电话给消费者时。来自<code>@KafkaListener</code>注释方法的pause()会发生什么?消费者立即暂停,或者我可以接收到同一主题分区的其他偏移量上的其他消息。例如,我有偏移量为3的“message1

  • :) 我已经在一个(奇怪的)情况中结束了自己,简单地说,我不想使用来自Kafka的任何新记录,因此暂停主题中所有分区的sparkStreaming消费(InputStream[ConsumerRecord]),执行一些操作,最后,恢复消费记录。 首先这可能吗? 我一直在尝试这样的事情: 但是我得到了这个: 任何帮助我理解我遗漏了什么,以及为什么当消费者明确分配了分区时我会得到空结果的帮助都将受到欢

  • 有些情况下,例如爬取大的站点,我们希望能暂停爬取,之后再恢复运行。 Scrapy通过如下工具支持这个功能: 一个把调度请求保存在磁盘的调度器 一个把访问请求保存在磁盘的副本过滤器[duplicates filter] 一个能持续保持爬虫状态(键/值对)的扩展 Job 路径 要启用持久化支持,你只需要通过 JOBDIR 设置 job directory 选项。这个路径将会存储 所有的请求数据来保持一

  • 问题内容: 有没有一种方法可以使用ExecutorService暂停/恢复特定线程? 想象一下,我想停止id == 0的线程(假设为每个线程分配了一个增量ID,直到达到线程池的大小为止)。 过了一会儿,通过按下一个按钮,我想恢复该特定线程,并将所有其他线程保留为当前状态,这些状态可以暂停或恢复。 我在Java文档中发现了PausableThreadPoolExecutor的未完成版本。但这不适合我

  • 问题内容: 我试图谷歌,并从这个论坛上寻找我的问题的解决方案,但到目前为止没有运气。我想通过单击图片来暂停CSS3动画(图像幻灯片放映),并通过单击图片来恢复到相同的动画。 我知道如何暂停幻灯片放映,我也能够将其恢复一次,但是如果尝试暂停并恢复多次以上,它将停止工作。这是我的代码的样子: 我不想使用任何JS库(例如jQuery)或任何其他外部解决方案。 我的猜测是我的函数内部的函数仍在运行,这就是