【问题标题】:How do I know when asynchronous JavaScript execution complete in Rhino我如何知道 Rhino 中的异步 JavaScript 执行何时完成
【发布时间】:2020-01-15 13:25:14
【问题描述】:

我有一段 JavaScript 代码,它调用了一些异步 API,而且效果很好。但是我还需要调用其他 API 来报告脚本执行完成的时间。问题是Context.evaluateString(...) 立即返回,但脚本代码继续执行,因为它的异步性质。 JS 示例:

function f1(function (err, res) {
  function f2(function (err, res) {
    function f3(function (err, res) {
      handleResult(err, res);
      // ideally I need to know when handleResult(...) has completed execution
      // but Rhino's Context.evaluateString(...) returns immediately
      // after f1() is called, but script continues execution
    });
  });
});

是的,我可以在脚本中添加一些方法,以便在所有操作完成后从脚本中调用它,并在 Java 端处理它,但这会迫使我每次都调用它。这只是解决方法。 但是我需要更通用的方式而不对脚本代码应用任何规则。 另外,如果客户忘记从脚本中调用sendResult() 怎么办?另一端的应用程序将永远等待结果。所以我需要防弹解决方案。

在 iOS 中,使用 javascriptcore 我只是在添加到脚本引擎顶级对象被销毁时做出反应,但在 Java 中这个技巧不起作用,因为与 Objective-C/Swift 不同,Java 不是引用计数而是使用 GC 和你永远不知道什么时候会释放对象。

【问题讨论】:

  • 欢迎来到 SO!您需要编辑您的问题以包含您的代码。如需更多帮助,请参阅how to ask
  • “脚本执行完成时我还需要调用其他 API 来报告” 那么是什么阻止您这样做呢?大概您正在调用的异步 API 将在完成后调用 JavaScript 函数,对吧?然后该函数执行“调用其他 API 进行报告”。如果这是 100% JavaScript,这就是你会做的事情,而且这并没有改变,因为你还涉及 Java。如果你想让 JavaScript 回调函数进一步调用一些 Java 代码进行后续处理,那么只需让 JavaScript 代码调用一个 Java 方法即可。
  • @Andreas 谢谢。是的,我可以做这个解决方法,但它对我来说看起来并不漂亮,将被用作最后的手段。我不敢相信 Rhino 中没有任何东西可以通知脚本执行完成。我想让脚本对客户更容易,并在 Java 方面做更多的事情。
  • handleResult 是返回承诺还是接受回调?
  • @3limin4t0r 是同步的。

标签: javascript java rhino


【解决方案1】:

我没有使用 Rhino 的经验,所以对这个答案持保留态度。但是,这个答案可能会引导您朝着正确的方向前进。

documentation 声明:

evaluateString

...

返回:

计算字符串的结果

所以我会创建一个由 JavaScript 返回的Future。执行handleResult 后解决future。然后在 Java 端,只需将结果转换为正确的对象,然后 wait 即可解析要解析的值。

// create an empty task
const future = new java.util.concurrent.FutureTask(function () {});

f1(function (err, res) {
  f2(function (err, res) {
    f3(function (err, res) {
      handleResult(err, res);

      // run the empty task, doing nothing more than resolving the future
      future.run();
    });
  });
});

// return future to evaluateString
future;

您可以在 JavaScript here 中找到有关 Java 对象的更多信息。

【讨论】:

  • 谢谢。这与从脚本调用特殊函数来通知 Java 端没有什么不同。我试过这个并且它有效。但我希望收到来自 Rhino 引擎的通知,而不是来自脚本。这是一种解决方法,但我需要一个具体的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-22
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多