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의 경우 슬리핑 스레드 및 wakener를 생성하려면 Lwt.task을 사용하고 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