Nashorn - Синхронное Java против асинхронного несоответствия Javascript
У меня есть Java-проект, использующий Nashorn для запуска некоторого JavaScript-кода, специально для того, чтобы воспользоваться некоторыми библиотеками JS.
Проблема, с которой я сталкиваюсь, заключается в том, что мое Java-приложение является синхронным приложением, которое получает HTTP-запрос и отвечает. Однако в Javascript распространены библиотеки, которые получают обратные вызовы.
Итак, мои вопросы:
- Как бороться с несоответствием импеданса между синхронизацией Java и асинхронным 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 ответ
Для преобразования асинхронного в синхронный API в Clojure вы можете использовать promise
:
Javascript код:
function getCustomer(id, clojureCallback) {
var jsCallback = function(result) { clojureCallback.invoke(result); };
callHttp("http://api/customer/" + id, jsCallback);
}
Код закрытия:
(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 IFn
) вызывая его с результатом (clojureCallback.invoke(result)
в коде Javascript). Тогда результат может быть deref
ed (@
это макрос для чтения deref
).