第一次运行中设置的值在第二次运行中看不到并因此收到消息“奇怪!在第二次运行中找不到值”的原因是因为每次我调用:
cache.flatMap { ref
我得到了一个不同的“ref”实例
但是为什么呢?
有没有办法修复/执行此操作,以便第二次运行可以找到第一次运行中设置的值?
import cats.effect.kernel.Ref
import cats.effect.{IO, IOApp}
object SomeMain2 extends IOApp.Simple {
val cache: IO[Ref[IO, Option[String]]] = Ref.of[IO, Option[String]](None)
override def run: IO[Unit] = {
for {
_ <- firstRun
_ <- secondRun
} yield IO()
}
private def firstRun: IO[Unit] = cache.flatMap { ref =>
val checkValueBeforeSet = ref.get.flatMap {
case Some(v) => IO(println(v))
case None => IO(println("no value found in firstRun"))
}
val doSetAction = ref.set(Some("abc")).map(_ => println("set action done in firstRun"))
val checkValueAfterSet = ref.get.flatMap {
case Some(v) => IO(println(s"as expected value found: $v"))
case None => IO(println("unexpected still no value set!"))
}
for {
_ <- checkValueBeforeSet
_ <- doSetAction
_ <- checkValueAfterSet
_ <- IO(println(s"ref: $ref"))
} yield IO()
}
private def secondRun: IO[Unit] = cache.flatMap { ref =>
val checkValue = ref.get.flatMap {
case Some(v) => IO(println(v))
case None => IO(println("strange! no value found in secondRun"))
}
for {
_ <- checkValue
_ <- IO(println(s"ref: $ref"))
} yield IO()
}
}
输出:
no value found in firstRun
set action done in firstRun
as expected value found: abc
ref: cats.effect.kernel.SyncRef@14dfe50a
strange! no value found in secondRun
ref: cats.effect.kernel.SyncRef@1bca3dbe
这与第 1 部分中的问题相同,但形式不同。第一个问题中 Mateusz 的答案在这里仍然适用。让我在这种情况下为您进行调整。
您需要在所有程序中重用相同的Ref
实例:
val cache: IO[Ref[IO, Option[String]]] = Ref.of[IO, Option[String]](None)
override def run: IO[Unit] = {
for {
cacheRef <- cache
_ <- firstRun(cacheRef)
_ <- secondRun(cacheRef)
} yield IO()
}
private def firstRun(cacheRef: Ref[...]): IO[Unit] = {
// do something with cacheRef
}
private def secondRun(cacheRef: Ref[...]): IO[Unit] = {
// do something with cacheRef
}