使用 Cats Effect Ref 作为缓存 - 第 2 部分

问题描述 投票:0回答:1

第 1 部分

第一次运行中设置的值在第二次运行中看不到并因此收到消息“奇怪!在第二次运行中找不到值”的原因是因为每次我调用:

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
scala functional-programming cats-effect
1个回答
0
投票

这与第 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 }
    
© www.soinside.com 2019 - 2024. All rights reserved.