Nashorn - 同步Java与异步Javascript阻抗不匹配

时间:2016-11-22 21:05:05

标签: javascript java asynchronous clojure nashorn

我有一个使用Nashorn的Java项目专门运行一些javascript代码来利用一些JS库。

我面临的问题是我的Java应用程序是一个接收HTTP请求并响应的同步应用程序。但是在Javascript中,通常会有接收回调的库。

所以我的问题是:

  • 如何处理sync java和async javascript之间的阻抗不匹配。有没有办法等待回调被调用,只有在响应之后?
  • 如何将Java回调传递给Javascript函数?
  • 或者有没有办法阻止Javascript代码,直到回调完成?

下面是一个示例代码。该项目实际上是在Clojure中,但我为了这个例子而输入java:

@RequestMapping(value = "/{customerId}", method = RequestMethod.GET, produces="application/json")
@ResponseStatus(value = HttpStatus.OK)
public @ResponseBody Customer getShoppingCart(@PathVariable String customerId) {
    return getById(customerId).toJson();
}

public Customer getById( String id ) {
     nashorn.invokeFunction("javascriptFunction", expectedCallbackFunction)
}

谢谢!

1 个答案:

答案 0 :(得分:1)

要在Clojure中将异步API转换为同步API,您可以使用promise

Javascript代码:

function getCustomer(id, clojureCallback) {
  var jsCallback = function(result) { clojureCallback.invoke(result); };
  callHttp("http://api/customer/" + id, jsCallback);
}

Clojure代码:

(def js-engine ...)

(defn get-customer-by-id [id]
  (let [customer-promise (promise)]
    (.invokeFunction js-engine "getCustomer" (object-array [id customer-promise]))
    @customer-promise))

可以通过调用deliver函数或(因为Clojure promise对象实现IFn)通过调用结果(Javascript代码中的clojureCallback.invoke(result))来提交Promise结果。然后结果可以是deref ed @deref的读者宏。