我正在将Future
代码转换为IO
。我有与此类似的代码
def doSomething: Future[Foo] = {
Future {
//some code the result of which we don't care about
}
Future {
//Foo
}
}
然后在程序结尾,我
doSomething.unsafeRunSync
。如何在保持第一个Future
的即发即弃功能的同时将这些IO
转换为Future
?在使用IO
的异步API时,我担心稍后在unsafeRunSync
上调用doSomething
时意外阻塞线程。
最佳答案
仅使用cats-effect
的解决方案可以使用IO.start
。再加上您将永远不会加入生成的Fiber
的事实,将看起来像这样:
import cats.effect._
import cats.implicits._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
object ExampleApp extends App{
val fireAndForget =
IO(println("Side effect pre-sleep")) *>
IO.sleep(2.seconds) *>
IO(println("Side effect post-sleep"))
val toBeUsed = IO{
println("Inside second one")
42
}
val result = for {
fiber <- IO.shift *> fireAndForget.start
res <- toBeUsed.handleErrorWith { error =>
// This is just in case you 'toBeUsed' can actually fail,
// and you might want to cancel the original side-effecting IO
fiber.cancel *> IO.raiseError(error) }
} yield res
println(result.unsafeRunSync())
println("Waiting 3 seconds...")
IO.sleep(3.seconds).unsafeRunSync()
println("Done")
}
在大多数情况下,这将打印类似于以下内容的内容:
Side effect pre-sleep
Inside second one
42 // Up until here, will be printed right away
Waiting 3 seconds... // It will then be waiting a while
Side effect post-sleep // ...at which point the side effecting code terminates
Done
最后,这是有关Fiber和IO.shift的更多详细信息
关于scala - 对Cats Effect IO进行认真评估并忘记行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50354729/