beholder
10/17/2019, 7:36 AMaltavir
10/17/2019, 7:45 AMbeholder
10/17/2019, 7:46 AMaltavir
10/17/2019, 7:50 AMbeholder
10/17/2019, 7:51 AMaltavir
10/17/2019, 7:52 AMbeholder
10/17/2019, 7:53 AMaltavir
10/17/2019, 7:53 AMgildor
10/17/2019, 8:08 AMbeholder
10/17/2019, 8:13 AMgildor
10/17/2019, 8:18 AMbeholder
10/17/2019, 8:19 AMgildor
10/17/2019, 8:20 AMbeholder
10/17/2019, 8:21 AMgildor
10/17/2019, 8:21 AMbeholder
10/17/2019, 8:30 AMelizarov
10/17/2019, 8:31 AMgildor
10/17/2019, 8:42 AMthevery
10/18/2019, 6:05 PMЯ бы рекомендовал для начала прочесть официальный гайдТам пока до сути дойдёшь уже забудешь, что хотел, уж лучше "неофициальный блог" читать, там про юзкейсы написано
altavir
10/18/2019, 6:06 PMthevery
10/18/2019, 6:07 PMaltavir
10/18/2019, 6:07 PMthevery
10/18/2019, 6:13 PMthevery
10/18/2019, 6:16 PMgildor
10/19/2019, 2:20 AMТам пока до сути дойдёшь уже забудешь, что хотелМне кажется просто пока не прочтешь и не поймешь о чем это вообще, лучше не соваться Там большая часть доки как раз про юзкейсы
мне сильно не хватает Single/Maybe вместо голых suspend-ова что хочется добится?
но это не соглашение на уровне контрактаУ корутинь тоже, на уровне susped функций
elizarov
10/19/2019, 6:55 AMtypealias Single<T> = suspend () -> T
. Но зачем?thevery
10/19/2019, 1:19 PMelizarov
10/19/2019, 1:25 PMthevery
10/19/2019, 10:38 PMsingle()
.map(::func1)
.subscribeOn().observeOn().subscribe()
с suspend
вместо single
придётся func1
(или оба `func1`+`suspend`) заворачивать в withContext
или переписывать тоже на suspend
.Maybe
, то это обычно своеобразный guard, типа
maybeLoadUser()
.map(::loadExtendedData)
.subscribeOn().observeOn().subscribe(::showNotification)
на suspend придётся делать suspendLoadUserOrNull
и либо городить заборы, либо делать early returnМета-замечание: Котлин прагматичный язык.Абсолютно согласен, потому и возмущаюсь некоторыми штуками в корутинах. Ручной вызов await + лишняя переменная (когда нужно сделать 2 или больше разных параллельных запросов) - БОЛЬ, даже zip и тот лучше выглядит.
gildor
10/20/2019, 3:48 AMРучной вызов await
val (a, b) = awaitAll(async { "a" }, async { "b" })
elizarov
10/20/2019, 1:21 PMthevery
10/20/2019, 1:26 PMval a by async { "a" }
, но это мы как раз год назад обсуждали.elizarov
10/20/2019, 1:27 PMmaybeLoadUser()
.map(::loadExtendedData)
.subscribeOn().observeOn().subscribe(::showNotification)
становится вот таким
val user = maybeLoadUser() ?: return
val data = loadExtendedData(user)
showNotification(data)
Ну а для тех, кто не любит дополнительные переменные, можно написать:
maybeLoadUser()
?.let(::loadExtendedData)
?.let(::showNotification)
В любом случае это 100% такой же как код, так я если бы никаких медленных сетевых операций не было.awaitAll + async
можно сделать extension в пару строк у себя в проекте, если вот прямо так часто нужно:
val (a, b) = awaitAllAsync({ "a" }, { "b" })
thevery
10/20/2019, 5:58 PMval user = maybeLoadUser() ?: return
maybeLoadUser
становится nullable (не очень большая проблема, но всё равно неявный контракт) и это как раз тот early return, про который я выше говорил
val data = loadExtendedData(user)loadExtendedData всё равно нужно качественно на suspend переписать или завернуть в async
elizarov
10/20/2019, 7:33 PMmap(::loadExtendedData)
(а не flatMap
), то я из этого делаю вывод, что loadExtendedData
это какая синхронная локальная операция (достает что-то из кэша?). Не нужно её на suspend переписывать.thevery
10/20/2019, 7:47 PMelizarov
10/20/2019, 8:05 PM.subscribeOn(someBackgroundDispatcher)
. С корутинами же в этом случае вы пишете withContext(someBackgroundDispatcher) { loadExtendedData(user) }
. Разницы вроде как нет.thevery
10/20/2019, 8:09 PMelizarov
10/20/2019, 8:16 PMwithContext
на всё. Вреда от него не будет.thevery
10/21/2019, 11:52 PM