Понимание IO монады - PullRequest
       8

Понимание IO монады

0 голосов
/ 14 ноября 2018

Я пытаюсь понять асинхронные вычисления на cats.effect.IO примерах и получил некоторое недопонимание. Метод unsafe unsafeRunAsync похоже на асинхронный запуск базового эффекта (я ожидал, что будет предоставлено немного ContextShift). Но метод выглядит просто так:

final def unsafeRunAsync(cb: Either[Throwable, A] => Unit): Unit =
  IORunLoop.start(this, cb)

Не указано ни ContextShift, ни ExecutionContext. Вот очень простой пример:

object TestIo extends App {
  println(s"Main thread = ${Thread.currentThread().getName}")
  val io = IO {
    println(s"Effect thread = ${Thread.currentThread().getName}")
    Thread.sleep(1000)
  }
  io.unsafeRunAsync(_ => println(s"Callback thread = ${Thread.currentThread().getName}"))
  println(s"Finished")
}

Выход

Main thread = main
Effect thread = main
Callback thread = main
Finished

Как вы видите, здесь все выполняется в главном потоке синхронно . Не могли бы вы объяснить unsafeRunAsync? Мне кажется, это так же, как unsafeRunSync.

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

О

Не предоставляются ни ContextShift, ни ExecutionContext.

В cats.effect.IO

есть переключатель контекста

Смотрите этот блог: https://www.jaspervanzandbeek.com/scala/cats-io-monad/

Вот пример оттуда:

def blockingOperation(): String = {
  // Read from file
  ...
}

val result: IO[String] = for {
  _ <- IO.shift(executionContextForBlockingOperations)
  result <- IO { blockingOperation() }
  _ <- IO.shift(mainExecutionContext)
} yield result
0 голосов
/ 14 ноября 2018

Разница между unsafeRunSync и unsafeRunAsync заключается в том, заблокирован ли поток.Вы заставляете свою нить блокировать, используя Thread.sleep в теле своей IO монады.Делая это, вы заставляете его вести себя синхронно.

Поскольку IO является монадой, она все равно будет выполнять вычисления последовательно.Поэтому ваши отпечатки всегда будут в таком порядке.

...