如何让java等待javascript?

时间:2015-07-28 14:00:39

标签: javascript java asynchronous

我尝试在TomTom地图上路由并从路由方法获得回调。 所以我在JavaFx中编写了一个Java应用程序,并在JavaFX的webview上显示了TomTom Map。

现在我的问题:我从JavaCode调用Javascript中的方法并希望从路由方法中获取响应,但这需要时间并且是异步的。我只是从javascript获取Promise对象而不是响应......

我改变了javscript函数,不再使用promises了。

已编辑的代码:

JavaCode:

package application;

import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Properties;

import javafx.application.Application;
import javafx.concurrent.Worker.State;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import netscape.javascript.JSObject;

public class Main extends Application{

static JSObject window;
static Stage primaryStage;

public void start(Stage primaryStage) {



try {
        Browser browser = new Browser();
        browser.getWebEngine().getLoadWorker().stateProperty()
        .addListener((obs, oldValue, newValue) -> {
            if (newValue == State.SUCCEEDED) {

                window = (JSObject) browser.getWebEngine().executeScript("window");

                System.out.println("Now call gogo");
                System.out.println("gogo Output: " + window.call("gogo"));

                WebController webControl= new WebController(browser, window);
                window.setMember("clickController", webControl);

                System.out.println("First it will go over here and print this");

                LocalDate date = LocalDate.now();
                try {
                    FileWriter fw = new FileWriter("output/"+date+".csv", true);
                    BufferedWriter bw = new BufferedWriter(fw);
                    bw.append(LocalTime.now() + ";" + delay + "\n");
                    bw.close();
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        Scene scene = new Scene(browser, Color.web("#666970"));
        primaryStage.setTitle("TestApplication");
        primaryStage.setScene(scene);
        primaryStage.show();
    } catch(Exception e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    launch(args);
}
}

使用Javascript:

    function gogo(){
    var data = goTask(function(data) {
    console.log(data.summary.totalDistanceMeters);
    clickController.print("after all that java stuff it will invoke this syso")
    clickController.print("output Routing function: " + data.summary.totalDistanceMeters);
    clickController.print("gogo output with invoking java from javascript");    
    return data;
    });
    return data;
    }

    function goTask(call){
    function callback(d){
        call(d);
    }
    routeMe(callback);
    function routeMe(callbackFunc){
        var points = [ [48.7061643,9.1664228], [48.7322085,9.0489835] ]; 
        var service = new tomtom.services.RoutingService("'ApiKey'");
        var options = {
            includeTraffic: true
            // avoidTolls: true
        };
        service.getRoute(points, options,callbackFunc);
    }
    }

输出:

Now call gogo
gogo Output: undefined
First it will go over here and print this syso
WebController Syso: after all that java stuff it will invoke this
WebController Syso: output Routing function: 9419
WebController Syso: gogo output with invoking java from javascript

问题是Java不等待Javascript ......

任何人都可以帮助我吗?

修改

@Bonatti我在

上运行它

ScriptEngineFactory getEngine - > Oracle Nashorn

ScriptEngine getLanguage - > ECMAScript的

2 个答案:

答案 0 :(得分:0)

我不知道tomtom服务。但是,通过阅读您的代码return new Promise正在按预期工作,因为您收到了Promise 我建议使用另一个函数来接收route,然后使用SOAP将数据读入您的应用程序

答案 1 :(得分:0)

现在你正在向Java返回一个Promise,它不知道如何处理它。它不会等待承诺得到履行,因为没有办法解释承诺并没有太多发生。

您只能在Javascript中处理此承诺,例如.then(...),其中您实际上处理了您期望的结果(延迟)。

强制同步使用的承诺不起作用,如果你想在Javascript(Call An Asynchronous Javascript Function Synchronously)中同步处理你的函数结果,那将是同样的问题。

在这里尝试@Evan Knowles的回答,但改为使用回调:

  

我们要为成功的状态设置一个监听器 - 基本上我们要在JavaScript中注入一个Java类并让它回拨给我们。让我们创建一个WebController来检查传入的内容并打印出ID

How to catch return value from javascript in javafx?