https://kotlinlang.org logo
#coroutines
Title
# coroutines
a

Allan Wang

12/21/2018, 12:17 AM
If I have code that previously used the continuation style:
Copy code
doA {
  doB {
    doC()
  }
}
And I want to make them all in the same level, would it be done like the following?
Copy code
// Original
fun doA(continuation: () -> Unit) {
  // some action
  continuation()
}

// New
suspend fun doA() = suspendCoroutine<Unit> {
  // some action
  it.resume(Unit)
}
Then I do something like
Copy code
launch {
  doA()
  doB()
  doC()
}
Which should occur one after the other by default. My goal is just to remove the nested brackets. The reason I have continuation to begin with is that the actions I’m running deal with callbacks. Is there also a benefit to doing some potential safety checks before calling suspendCoroutine vs putting them all inside that wrapper? The delay function seems to do that.
g

gildor

12/21/2018, 12:26 AM
But I don't see any usage of callback here, why not just write your code sequentially, it's not clear for those examples why do you need callback and suspend
a

Allan Wang

12/21/2018, 12:30 AM
This is an example of an actual method I have:
Copy code
private fun setWebCookie(cookie: String?, callback: (() -> Unit)?) {
    with(CookieManager.getInstance()) {
        removeAllCookies { _ ->
            if (cookie == null) {
                callback?.invoke()
                return@removeAllCookies
            }
            L.d { "Setting cookie" }
            val cookies = cookie.split(";").map { Pair(it, SingleSubject.create<Boolean>()) }
            cookies.forEach { (cookie, callback) -> setCookie(FB_URL_BASE, cookie) { callback.onSuccess(it) } }
            Observable.zip<Boolean, Unit>(cookies.map { (_, callback) -> callback.toObservable() }) {}
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe {
                        callback?.invoke()
                        L.d { "Cookies set" }
                        L._d { cookie }
                        flush()
                    }
        }
    }
}
In android, remove all cookies and set cookies all take callbacks. I want to clear all cookies and then get set a bunch of cookies, before performing actions. All the other methods are similar.
d

Dico

12/21/2018, 12:44 AM
I think you should replace the implementation of your
doA
,
doB
and
doC
with
suspend
function and remove the callback parameters
Then you can call them sequentially from coroutine
g

gildor

12/21/2018, 2:49 AM
+1 to Dico, you just need suspend version of `removeAllCookies`/`setCookie`
You need something like that:
Copy code
suspend fun CookieManager.removeAllCookiesSuspend(): Boolean {
        return suspendCoroutine { cont ->
            removeAllCookies {
                cont.resume(it)
            }
        }
    }
I actually not sure why do you need Rx in this case
I think this function in general not really good, why do you want call callback on every cookie set you can just return result
and with coroutines you don’t need this Rx just to switch to main thread, you can use coroutines dispatcher for thaat
4 Views