是否可以等待异步函数解析并使用 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
互操作性文档向您展示了如何执行此操作。您可以使用 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();