我在玩 Funscript,想从我的工作流程中得到一些结果。我将那些天真的定义(没有结果单元格)添加到 Async 模块中。
static member RunSynchronously(workflow:Async<'T>, ?timeout:int,?cancellationToken:CancellationToken) =
let result = ref None
let token = defaultArg cancellationToken { Cell = None }
let (Cont f) = workflow
let aux = { StackCounter = ref 0; ExceptionCont = ignore;
CancelledCont = ignore; CancellationToken = token }
f { Cont = (fun v -> result := Some v); Aux = aux }
let r = !result
r.Value
static member StartChild(computation:Async<'T>,?millisecondsTimeout:int) =
async { return Async.FromContinuations(fun (cont, econt,ccnt) -> cont (Async.RunSynchronously computation)) }
在这种情况下有效
let test = async{ let t = async { let! r = async { return "inside" }
return "Hello" }
let! task = Async.StartChild t
let! res = task
return res
} |> Async.RunSynchronously
但是当被问及“真正”使用时会摔倒
let toto = Globals.document.createElement_img()
toto.id <- "toto"
Globals.document.body.appendChild(toto :> Node) |> ignore
let test = async{ let t = async { let! r = Async.AwaitJQueryEvent(j?toto.load)
return "Hello" }
let! task = Async.StartChild t
do toto.src <- "redundant.png"
let! res = task
return res
} |> Async.RunSynchronously
因为 j?toto.load 方法不会暂停并给我回电,并且会中断异步流程。我想这就是使用单线程 javascript 所做的事情。
什么是真正的解决方案?像在 F# 中那样实施暂停是唯一的方法吗?