Java 使用WebEngine执行多个脚本(或依赖于其他脚本的脚本)

Java 使用WebEngine执行多个脚本(或依赖于其他脚本的脚本),java,jquery,javafx,jquery-callback,javafx-webengine,Java,Jquery,Javafx,Jquery Callback,Javafx Webengine,我想使用WebEngine(JavaFX)在网页上执行一些JavaScript(和jQuery)并处理结果(使用Java代码)。 我有一个回调函数的问题,它们自己执行一些脚本 为了尽可能简单地说明我的问题,我制作了一个最小化的代码来显示不想要的结果(它只是更大项目的一部分) 因此,我创建了三个类: 浏览器-包装web引擎的类,用作加载网页和执行脚本的浏览器 JQueryFunction-一个类,列出了两个与jQuery回调函数一起使用的函数,可以通过多种方式实现。(基本上,它们应该是用户以自己的

我想使用WebEngine(JavaFX)在网页上执行一些JavaScript(和jQuery)并处理结果(使用Java代码)。
我有一个回调函数的问题,它们自己执行一些脚本

为了尽可能简单地说明我的问题,我制作了一个最小化的代码来显示不想要的结果(它只是更大项目的一部分)

因此,我创建了三个类:

  • 浏览器-包装web引擎的类,用作加载网页和执行脚本的浏览器
  • JQueryFunction-一个类,列出了两个与jQuery回调函数一起使用的函数,可以通过多种方式实现。(基本上,它们应该是用户以自己的方式实现的功能接口——但为了简单起见,我将其设置为普通功能)
  • Test-一个具有执行两个脚本的main方法的类
  • 浏览器

    测试

    当我运行测试时,第一个
    executeScript
    会按预期运行,并更改某些元素的文本(在索引编号之前)。
    但是第二个
    executeScript
    永远粘住了,粘住了GUI,实际上粘住了整个JavaFX应用程序

    我理解为什么会发生这种情况……
    executeScript
    方法调用WebEngine(通过
    平台.runLater
    )来执行jQuery,该jQuery迭代元素并调用Java函数(每次使用不同的参数)

    • 第一次执行(调用function1)从function1获取返回的字符串,并将其应用于元素的文本。(完全出乎意料)

    • 第二次执行(调用function2)执行调用Java函数的jQuery函数,但是Java函数需要执行更多的JavaScript(或jQuery),但是WebEngine在第一次执行完成之前不会执行。
      但是第一次执行不会完成,因为它取决于第二次执行的结果

    WebEngine的编程方式是只在一个线程(在FX线程内)中执行一个又一个(串行)任务

    有什么办法可以解决吗?
    为什么WebEngine仅限于在JavaFX应用程序下工作?

    为什么它必须只与一个线程一起工作?

    避免出现“死锁”的一种可能方法是,当您已经在GUI线程(JavaFX应用程序线程)中运行时,不要调用
    Platform.runLater
    。比如:

    public static Object executeScript(String script) throws InterruptedException, ExecutionException {
            if(Platform.isFxApplicationThread()) {
                return webEngine.executeScript(script);
            } 
            FutureTask<Object> task = new FutureTask<>(new Callable<Object>() {
                 @Override
                 public Object call() throws Exception {
                     return webEngine.executeScript(script);
                 }
             });
             Platform.runLater(task);
             return task.get();
    
        }
    
    公共静态对象executeScript(字符串脚本)引发InterruptedException,ExecutionException{
    if(Platform.isFxApplicationThread()){
    返回webEngine.executeScript(脚本);
    } 
    FutureTask task=新的FutureTask(新的可调用(){
    @凌驾
    公共对象调用()引发异常{
    返回webEngine.executeScript(脚本);
    }
    });
    Platform.runLater(任务);
    return task.get();
    }
    
    import java.util.concurrent.ExecutionException;
    
    public class JQueryFunction {
        public String function1(int index, String text) {
            return (index+1) + ": " + text;
        }
    
        public String function2(int index, String text) throws InterruptedException, ExecutionException {
            return (String) Browser.executeScript("$($(\".BlueArrows:eq(2) li\").find(\"a:first\")[index]).text();");
        }
    }
    
    public class Test {
        public static void main(String[] args) throws Exception {
            Browser.start();
            Thread.sleep(1000);  // Only used here to simplify the code
            Browser.load("https://docs.oracle.com/javase/tutorial/");
            Thread.sleep(3500);  // Only used here to simplify the code
            Browser.getWindow().setMember("javaApp", new JQueryFunction());
            Browser.executeScript("$(\".BlueArrows:eq(0) li\").find(\"a:first\").text(function(index, text) { return javaApp.function1(index, text); });");
            Browser.executeScript("$(\".BlueArrows:eq(0) li\").find(\"a:first\").text(function(index, text) { return javaApp.function2(index, text); });");
        }
    }
    
    public static Object executeScript(String script) throws InterruptedException, ExecutionException {
            if(Platform.isFxApplicationThread()) {
                return webEngine.executeScript(script);
            } 
            FutureTask<Object> task = new FutureTask<>(new Callable<Object>() {
                 @Override
                 public Object call() throws Exception {
                     return webEngine.executeScript(script);
                 }
             });
             Platform.runLater(task);
             return task.get();
    
        }