我正在寻找一个轻量级的库,它允许我,而不是写作:
val future1 = process1()
future1.onSuccess { process2() }
以下内容:
val future1 = process1()
future1.await()
process2()
没有阻塞线程(所以不是:Await.result(future1)
)也就是说,我想象一个基于continuation的库,它将后者转换为前者。
答案 0 :(得分:4)
塔卡看看Akka Dataflow Concurrency。看起来就像你想要的那样!
示例(请参阅documentation):
flow {
val f1 = flow { "Hello" }
val f2 = flow { "world!" }
f1() + " " + f2()
} onComplete println
Akka Dataflow自动使用Scala的Delimited Continuations,并在后台为您生成延续。
答案 1 :(得分:4)
我目前唯一知道的库 Akka DataFlow :http://doc.akka.io/docs/akka/snapshot/scala/dataflow.html
查看项目定义(https://github.com/akka/akka/blob/master/project/AkkaBuild.scala),似乎akka-dataflow没有太多的依赖关系,所以它应该非常轻量级。
<强>更新强> 以下是一个示例用法,取自akka-dataflow的文档:
flow {
val f1 = flow { "Hello" }
val f2 = flow { "world!" }
f1() + " " + f2()
} onComplete println
这清楚地说明了你可以用程序方式编写代码(尽管在引擎盖下这实际上已转换为map / flatMap链)。
作为另一个简单的替代,你考虑过只使用延续吗?它们使用起来有点冗长,但总的好处是相同的:从程序上编写代码而不是用显式的cps风格来混淆它。例如,上面的示例直接转换为以下纯scala代码:
{for {
f1 <- future( "Hello" );
f2 <- future( "world!" )
} yield f1 + " " + f2
} onComplete println
哪个没有那么不同。而且你找不到比没有库更轻量级的库(虽然我承认我仍然更喜欢简洁性方面的akka-dataflow,但只是略有差距)。
答案 2 :(得分:4)
这个问题是在一年前提出来的。 今天,一个比Akka Dataflow更有前途的替代方案是 scala-async ,可在https://github.com/scala/async获得。
Akka Dataflow依赖于不会主动维护的延续插件,并且正在弃用。
另一方面, scala-async 不会尝试成为通用的cps解决方案,但只会解决异步代码的写入问题(我认为这是最常见的用例) cps插件)。
换句话说,它直接实现相当于Akka的flow
方法(在宏的帮助下),因此具有比cps插件更窄(更好定义)的范围,我认为这是允许它的关键整体上更好的实施。
以下是自述页面的示例:
val future = async {
val f1 = async { ...; true }
val f2 = async { ...; 42 }
if (await(f1)) await(f2) else 0
}
答案 3 :(得分:3)
Scala中还有一个数据流并发实现,您可能想要签出ScalaFLow。 github repo也包含论文PDF,非常详细地描述了这些工作。
Kai在this forum thread中提供了一个演示:
引用:
&#34;最小的演示(是的,看起来像期货):
val v = new Variable[Int]
flow { println( v() ) // suspends without blocking }
flow { v := 42 // resumes above flow }
&#34;