如何在api调用中的js方法中使用java中的graalvm等待?

问题描述 投票:0回答:1

是否可以等待异步函数解析并使用 graalvm 获取其输出?

为什么结果包含一堆额外的东西?

如何只获取返回值?

代码::

    public void main(  ) {

        try (Context ctx = Context.newBuilder("js")
                .allowAllAccess(true)
                .option("engine.WarnInterpreterOnly", "false")
                .build()) {

            String combinedScript = """
            // Define the async function
            async function dummyAsyncFunction() {
                console.log("dummyAsyncFunction()");
                // Simulate an asynchronous operation without setTimeout
                let start = new Date().getTime();
                while (new Date().getTime() - start < 2000) {
                    // Busy-wait for 1 second
                }
                // Return the message
                return "thanks for waiting";
            }
            
            // Call the async function and handle the returned value
            dummyAsyncFunction().then(message => {
                console.log(message); // Output: thanks for waiting
                return message;
            }).catch(e => {
                console.log("Error: " + e);
            });
        """;

            // Evaluate the combined script
            Value result = ctx.eval("js", combinedScript);
            System.out.println("result: "+result);

        } catch (Exception e) {
        }


    }

输出::

 run_server_script()
dummyAsyncFunction()
thanks for waiting
result: Promise{[[PromiseStatus]]: "resolved", [[PromiseValue]]: "thanks for waiting"}

这是我发现的唯一一个有点相关的 stackoverflow,但它对我没有帮助::

Java 中的 GraalVM JavaScript - 如何识别异步方法

Java 中的 GraalVM JavaScript - 如何识别异步方法

预期的行为是结果=“感谢等待”

更新::

我可以做这样的事情,但看起来不对,但它有效。它看起来不对,因为我必须解析数据的字符串::

Value result = ctx.eval("js", combinedScript); System.out.println("str: " + result.toString() ); 
Pattern pattern = Pattern.compile("\[\[PromiseValue\]\]:\\s*\"([^\"]*)\""); 
Matcher matcher = pattern.matcher(result.toString()); 

输出::

result: Promise{[[PromiseStatus]]: "resolved", [[PromiseValue]]: "thanks for waiting"} 

str: Promise{[[PromiseStatus]]: "resolved", [[PromiseValue]]: "thanks for waiting"} Extracted value: thanks for waiting 
java graalvm
1个回答
0
投票

互操作性文档向您展示了如何执行此操作。您可以使用 lambda 表达式对 Promise 调用

then()

Value result = ctx.eval("js", combinedScript);
Consumer<Object> finishedHandler = result -> System.out.println("promise resolved");
result.invokeMember("then", finishedHandler);

如果您想等待

Promise
,您可以使用
CountDownLatch
或类似的:

Value result = ctx.eval("js", combinedScript);
CountDownLatch awaiter = new CountDownLatch(1);
Consumer<Object> finishedHandler = result -> awaiter.countDown();
result.invokeMember("then", finishedHandler);
awaiter.await();
© www.soinside.com 2019 - 2024. All rights reserved.