В общем, если Task.async
используется - нет никакого способа, чтобы сделать композит Task
всегда оставаться в том же потоке, как cb
(обратный вызов) может быть вызвана из любого места (любая тема), так что в цепи, как:
Task
.delay("aaa")
.map(_ + "bbb")
.flatMap(x => Task.async(cb => completeCallBackSomewhereElse(cb, x)))
.map(_ + "ccc")
.unsafePerformSync
_ + "bbb"
собирается быть выполнен в потоке вызывающего абонента
_ + "ccc"
собирается быть выполнен в потоке Somewhereelse
«s, как scalaz не имеет никакого контроля над ним.
В принципе, это позволяет Task
быть мощным инструментом для асинхронных операций, поэтому он может даже не знать о пулах потоков или даже реализовать поведение без чистых потоков и ждать/уведомлять.
Однако существуют специальные случаи, когда он может работать в качестве абонентов спусков:
1) Нет Strategy
/Task.async
связанные вещи:
Task.delay("aaa").map(_ + "bbb").unsafePerformSync
unsafePerformSync
использует CountDownLatch ждать результата от runAsync
, так если на пути нет асинхронных/недетерминированных операций - runAsync
будет использовать caller's thread:
/**
* Run this `Future`, passing the result to the given callback once available.
* Any pure, non-asynchronous computation at the head of this `Future` will
* be forced in the calling thread. At the first `Async` encountered, control
* switches to whatever thread backs the `Async` and this function returns.
*/
def runAsync(cb: A => Unit): Unit =
listen(a => Trampoline.done(cb(a)))
2) У вас есть контроль над стратегиями исполнения. Так что this simple Java trick поможет. Кроме того, это уже реализовано в scalaz и называется Strategy.sequential
P.S.
1) Если вы просто хотите начать вычисление как можно скорее, используйте task.now
/Task.unsafeStart
.
2) Если вы хотите что-то не так сильно связанное с асинхронными вещами, но по-прежнему ленивое и стек-сейфом, вы можете взглянуть здесь (это для библиотеки Cats) http://eed3si9n.com/herding-cats/Eval.html
3) Если вам просто нужно инкапсулировать сторону -эффекты - взгляните на scalaz.effect
Посмотрите на описание unsafeStart отсюда. http://timperrett.com/2014/07/20/scalaz-task-the-missing-documentation/ –