我在玩Funscript,想要得到一些结果,我的工作流程。我将这些天真的定义(没有结果单元格)添加到异步模块中。
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#中)是否是唯一的方法?
发布于 2013-10-28 00:15:49
异步工作流的FunScript实现不使用当前JS中可能提供的任何高级线程机制。它只是在主浏览器线程上运行所有东西--这也是为什么它只为Async.StartImmediate提供映射的原因,因为这在逻辑上对应于标准F#运行时中的这种行为。
如果您想启动一个等待事件然后同步运行的工作流,那么在这个模型中这是不可能的--因此您无法合理地实现RunSynchronously,它将始终工作(要同步运行,您需要阻塞当前线程,但不能等待事件的发生……)
因此,我认为您需要以某种方式重构您的代码,这样它就不需要同步等待了--可能也是通过使调用方异步。
https://stackoverflow.com/questions/19624709
复制相似问题