5. fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and name is $userName")
}
fun getToken(userId : String) : String
fun getUserName(token : String) : String
fun sendMessage(message : String) : String
6. fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and name is $userName")
}
fun getToken(userId : String) : String
fun getUserName(token : String) : String
fun sendMessage(message : String) : String
7. fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and name is $userName")
}
@WorkThread
fun getToken(userId : String) : String
@WorkThread
fun getUserName(token : String) : String
fun sendMessage(message : String) : String
8. fun test(userId:String, callback:()->Unit){
getToken(userId) token-> {
getUserName(token) userName->{
sendMessage("User id is $userId and name is $userName"){
callback.invoke()
}
}
}
}
fun getToken(userId : String , callback:(String)->Unit)
fun getUserName(token : String , callback:(String)->Unit)
fun sendMessage(message : String , callback:(String)->Unit)
9. fun test(userId:String, callback:()->Unit){
getToken(userId) token-> {
getUserName(token) userName->{
sendMessage("User id is $userId and name is $userName"){
callback.invoke()
}
}
}
}
fun getToken(userId : String , callback:(String)->Unit)
fun getUserName(token : String , callback:(String)->Unit)
fun sendMessage(message : String , callback:(String)->Unit)
Callback hell
10. fun test(userId:String, callback:()->Unit){
getToken(userId) token-> {
getUserName(token) userName->{
sendMessage("User id is $userId and name is $userName"){
callback.invoke()
}
}
}
}
fun getToken(userId : String) : Single<String>
fun getUserName(token : String) : Single<String>
fun sendMessage(message : String)
14. fun sendMessage(userId:String){
1. val token = getToken(userId)
2. val userName = getUserName(token)
3. sendMessage("User id is $userId and name is $userName")
}
What we want
Sequential
15. Suspend
suspend fun getToken(userId : String) : String
suspend fun getUserName(token : String) : String
suspend fun sendMessage(message : String) : String
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and name is $userName")
}
16. suspend fun getToken(userId : String) : String {
// do request & suspend
return token
}
suspend fun getUserName(token : String) : String
suspend fun sendMessage(message : String) : String
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and name is $userName")
17. suspend fun getToken(userId : String) : String
suspend fun getUserName(token : String) : String
suspend fun sendMessage(message : String)
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and name is $userName")
}
Like Regular code !!
18. suspend fun getToken(userId : String) : String
suspend fun getUserName(token : String) : String
suspend fun sendMessage(message : String)
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and name is $userName")
}
Like Regular code !!
22. suspend fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object
fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;)Ljava/lang/String;
befroe
23. suspend fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object
fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;)Ljava/lang/String;
Kotlin bytecode for jvm
24. suspend fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object
fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;)Ljava/lang/String;
After
25. suspend fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object
fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;)Ljava/lang/String;
After
26. suspend fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object
fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;)Ljava/lang/String;
27. Continuation-passing style
In functional programming, continuation-passing style (CPS) is a style of
programming in which control is passed explicitly in the form of a continuation
fun test( ){
val token = requestToken()
val userId = getUserId(token)
}
fun test( ){
getToken { token->
val userId = getUserId(token)
}
}
Direct Style
28. Continuation-passing style
In functional programming, continuation-passing style (CPS) is a style of
programming in which control is passed explicitly in the form of a continuation
fun test( ){
val token = requestToken()
val userId = getUserId(token)
}
fun test( ){
getToken { token->
val userId = getUserId(token)
}
}
Direct Style
Continuation
29. Continuation-passing style
In functional programming, continuation-passing style (CPS) is a style of
programming in which control is passed explicitly in the form of a continuation
fun test( ){
val token = requestToken()
val userId = getUserId(token)
}
fun test( ){
getToken { token->
val userId = getUserId(token)
}
}
30. Continuation-passing style
In functional programming, continuation-passing style (CPS) is a style of
programming in which control is passed explicitly in the form of a continuation
fun test( ){
val token = requestToken()
val userId = getUserId(token)
}
fun test( ){
getToken { token->
val userId = getUserId(token)
}
}
CPS == Callback
31. How does it work
interface Continuation<in T> {
val context: CoroutineContext
fun resume(value: T)
fun resumeWithException(exception: Throwable)
}
32. class test(userId:String , sm : Continuation<Unit>) : Any{
val sm = CoroutineImpl {
fun doResume(...){
test(null,this)
}
var token : String
var userName : String
}
switch(sm.Label){
case 0:
sm.Label = 1
getToken(userId,sm)
break
case 1:
sm.Label = 2
getUserName(sm.token , sm)
break
case 2:
sm.Label = 3
sendMessage("User id is $userId and name is $userName")
break
}
}
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and
name is $userName")
}
33. class test(userId:String , callback : Continuation<Unit>) : Any{
val sm = CoroutineImpl {
fun resume(...){
test(null,this)
}
var token : String
var userName : String
}
switch(sm.Label){
case 0:
sm.Label = 1
getToken(userId,sm)
break
case 1:
sm.Label = 2
getUserName(sm.token , sm)
break
case 2:
sm.Label = 3
sendMessage("User id is $userId and name is $userName")
break
}
}
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and
name is $userName")
}
34. class test(userId:String , callback : Continuation<Unit>) : Any{
val sm = CoroutineImpl {
fun doResume(...){
test(null,this)
}
var token : String
var userName : String
}
switch(sm.Label){
case 0:
sm.Label = 1
getToken(userId,sm)
break
case 1:
sm.Label = 2
getUserName(sm.token , sm)
break
case 2:
sm.Label = 3
sendMessage("User id is $userId and name is $userName")
break
}
}
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and
name is $userName")
}
35. class test(userId:String , callback : Continuation<Unit>) : Any{
val sm = CoroutineImpl {
fun doResume(...){
test(null,this)
}
var token : String
var userName : String
}
switch(sm.Label){
case 0:
sm.Label = 1
getToken(userId,sm)
break
case 1:
sm.Label = 2
getUserName(sm.token , sm)
break
case 2:
sm.Label = 3
sendMessage("User id is $userId and name is $userName")
break
}
}
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and
name is $userName")
}
spending function
36. class test(userId:String , callback : Continuation<Unit>) : Any{
val sm = CoroutineImpl {
fun doResume(...){
test(null,this)
}
var token : String
var userName : String
}
switch(sm.Label){
case 0:
sm.Label = 1
getToken(userId, sm )
break
case 1:
sm.Label = 2
getUserName(sm.token , sm)
break
case 2:
sm.Label = 3
sendMessage("User id is $userId and name is $userName")
break
}
}
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and
name is $userName")
}
Restore state
37. class test(userId:String , callback : Continuation<Unit>) : Any{
val sm = CoroutineImpl {
fun resume(...){
test(null,this)
}
var token : String
var userName : String
}
switch(sm.Label){
case 0:
sm.Label = 1
getToken(userId,sm)
break
case 1:
sm.Label = 2
getUserName(sm.token , sm)
break
case 2:
sm.Label = 3
sendMessage("User id is $userId and name is $userName")
break
}
}
suspend fun test(userId:String){
val token = getToken(userId)
val userName =
getUserName(token)
sendMessage("User id is $userId
and name is $userName")
}
49. How to cancel ?
val job = GlobalScope.launch(Dispatchers.IO) {
val data = APIRepo.getUser()
withContext(Dispatchers.Main) {
showMesssgae(data.message)
}
}
job.cancel()
// RxJava Disposable
è§ŁééæŻäžćstep by step çsimple case
It just a simple code , concept
Every step is depend on last stept çžäșäŸèłŽ
getToken ćèšç”ŠäșuserIdćŻä»„æżć°token
getUserName inpu token can get user name
Last step is just print the userid & usaname
But what if the case going to a liitl bit different
When getToken this method need to create new thread witch mean workThread to do async
also the getUserName need it too
The last step also print message