2016-07-13 8 views
-1

js_of_ocamlを使用してJS関数をラップし、OCaml内で呼び出すことができます。私は、JS関数が非同期(すなわち、約束を含み、時間がかかる)のときに、実例を作ることができません。非同期JS関数をラップしてOCamlで使用できますか?

非同期JS関数JSfunラップしたいのは以下の通りです。変数xは2秒後に"here"に設定され、これが返す値です。

function JSfun() { 
    var x = "before"; 
    return new Promise(function(resolve, reject) { 
    setTimeout(function() { 
     append("inside setTimeout"); 
     x = "here"; 
     resolve(x); 
    }, 2000); 
    }) 
} 

我々は成功したJSでJSfunを呼び出し、予想通り"runJS here"を得ることができます:

function runJS() { 
    JSfun().then(function(res) { 
    append("runJS " + res) 
    }) 
} 

しかし、OCamlのことで、このチェーンを模倣することは困難です。 OCamlの中JSfunをラップするために、我々が使用する必要がありますようだ:

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") 
    ); 

をそして私はこのような呼び出し以外のアイデアを持っていない。当然のことながら

function runOCaml() { 
    var res = OCamlcall("abc"); 
    append(res); 
} 

が、それは動作しません。私たちはやります"inside setTimeout"が表示されます。これはJSfunが呼び出されたことを示しますが、戻り値はありませんでした。

ここにはjsfiddleがあります。同期JS関数をラッピングする実例も作成します。 OCamlでは、ラッピングは次のようになります。

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") 
    ); 

誰にも解決策、アイデア、または回避策がありますか?

答えて

1

js関数が非同期の場合、OCamlの関数も非同期である必要があります。つまり、LwtまたはAsyncを使用する必要があります。だから、Lwtの場合は、おそらくLwt.taskを使用してスリープスレッドとwakenerを作成し、wakenerでコールバックをPromisesの.thenメソッドに渡し、関数からスリープスレッドを返します。

(いくつかの種類は、おそらく一般的すぎる)のようになりますコード:

class type promise = 
    object 
    method then_ : ('a -> 'b) callback -> 'b meth 
    end 

let ocamlcall() = 
    let t, w = Lwt.task() in 
    let wakeup = Js.wrap_callback (fun r -> Lwt.wakeup t r) in 
    let (promise : promise Js.t) = Js.Unsafe.fun_call jsfunc [||] in 
    let() = ignore @@ promise##then_ wakeup in 
    t 

注:私はこのコードをテストしていませんが、それがどのように非同期JSの機能と対話するために、あなたの一般的なアイデアを与える必要があります。

jsono自体がjsonpでどのように動作するかを確認することもできます。https://github.com/ocsigen/js_of_ocaml/blob/master/lib/jsonp.ml

関連する問題