We could use js_of_ocaml to wrap a JS function and thus call it within OCaml. I cannot make a working example when the JS function is asynchronous (ie, includes promises and takes time).
The asynchronous JS function JSfun
I want to wrap is as follows. The variable x
is set to "here"
after 2 seconds, and this is the value I want to return.
function JSfun() {
var x = "before";
return new Promise(function(resolve, reject) {
setTimeout(function() {
append("inside setTimeout");
x = "here";
resolve(x);
}, 2000);
})
}
We could successfully call JSfun
in JS and get "runJS here"
as expected:
function runJS() {
JSfun().then(function(res) {
append("runJS " + res)
})
}
However, it is hard to imitate this chaining by OCaml. To wrap JSfun
in OCaml, it seems that we have to use:
Js.Unsafe.global##.OCamlcall := Js.wrap_callback
(fun _ ->
let m = Js.Unsafe.fun_call (Js.Unsafe.js_expr "JSfun") [||] in
Js.string ((Js.to_string m) ^ " Via OCaml")
);
And I don't have other idea than calling like this:
function runOCaml() {
var res = OCamlcall("abc");
append(res);
}
Unsurprisingly, it does not work: we do see "inside setTimeout"
printed, which proves JSfun
has been called, but the return value was not there.
Here is the jsfiddle. I also make a working example of wrapping synchronous JS function. In OCaml, the wrapping is:
Js.Unsafe.global##.OCamlcallSync := Js.wrap_callback
(fun _ ->
let m = Js.Unsafe.fun_call (Js.Unsafe.js_expr "JSfunSync") [||] in
Js.string ((Js.to_string m) ^ " Via OCaml")
);
So does anyone have a solution, an idea or a workaround?