Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Coroutinesから紐解くKtorの仕組み / Revealing Ktor with c...

Coroutinesから紐解くKtorの仕組み / Revealing Ktor with coroutines

Kotlin Fest 2019 で行った「Coroutinesから紐解くKtorの仕組み」の資料です。

Avatar for Yuji Koyano

Yuji Koyano

August 24, 2019
Tweet

More Decks by Yuji Koyano

Other Decks in Programming

Transcript

  1. fun Application.main() { routing { get("/kotline_fest") { call.respondText { "Kotlin

    Fest 2019!” } } } } Featureͷinstallྫ w จࣈྻΛฦ͢࠷খͷΞϓϦέʔγϣϯͷίʔυ
  2. fun Application.main() { install(DefaultHeaders) install(CallLogging) routing { get("/kotline_fest") { call.respondText

    { "Kotlin Fest 2019!” } } } } Featureͷinstallྫ w JOTUBMMϝιουΛ࢖༻ͯ͠ΞϓϦέʔγϣϯʹػೳ௥Ճ
  3. 1IBTF 1IBTF 1IBTF 1IBTF { setHeader() } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } ύΠϓϥΠϯػߏͷΠϝʔδ
  4. { setHeader() } { getAuth(userID) } { logging(response) } {

    saveProfile( userID, profile ) } w ,UPS͸ϦΫΤετΛड͚ΔͱίϧʔνϯΛ։࢝ͯ͠
 ܭࢉύΠϓϥΠϯʹׂΓ౰ͯΒΕͨॲཧΛ࣮ߦ͍ͯ͘͠ 1IBTF 1IBTF 1IBTF 1IBTF
  5. { asyncFun(context) } { getAuth(userID) } { logging(response) } {

    saveProfile( userID, profile ) } w ,UPS͸ϦΫΤετΛϋϯυϦϯά͢ΔͱίϧʔνϯΛ։࢝ͯ͠ ܭࢉ1JQFMJOFʹׂΓ౰ͯΒΕͨॲཧΛ࣮ߦ͍ͯ͘͠ 1IBTF 1IBTF 1IBTF 1IBTF override fun handle(ɾɾɾ) { try { ɾɾɾ launch(dispatcher + JettyCallHandlerCoroutineName) ɹɹɹɹɹɹɹɾɾɾ try { pipeline().execute(call) } catch (cancelled: CancellationException) { ɹɹɹɹɹɹɹɹɹɹɾɾɾ } } } catch (ex: Throwable) { ɹɹɹɹɹɹɹɾɾɾ } }
  6. { asyncFun(context) } { getAuth(userID) } { logging(response) } {

    saveProfile( userID, profile ) } w ,UPS͸ϦΫΤετΛϋϯυϦϯά͢ΔͱίϧʔνϯΛ։࢝ͯ͠ ܭࢉ1JQFMJOFʹׂΓ౰ͯΒΕͨॲཧΛ࣮ߦ͍ͯ͘͠ 1IBTF 1IBTF 1IBTF 1IBTF override fun handle(ɾɾɾ) { try { ɾɾɾ launch(dispatcher + JettyCallHandlerCoroutineName) ɹɹɹɹɹɹɹɾɾɾ try { pipeline().execute(call) } catch (cancelled: CancellationException) { ɹɹɹɹɹɹɹɹɹɹɾɾɾ } } } catch (ex: Throwable) { ɹɹɹɹɹɹɹɾɾɾ } }
  7. { setHeader() } { getAuth(userID) } { logging(response) } {

    saveProfile( userID, profile ) } w ܭࢉύΠϓϥΠϯ͸1JQFMJOF1IBTFʹΑͬͯॲཧͷॱংΛఆٛ
 1JQFMJOF1IBTFຖʹ೚ҙͷॲཧΛׂΓ౰͍ͯͯ͘͜ͱʹΑͬͯ
 ύΠϓϥΠϯશମͷॲཧΛܾఆ͢Δ͜ͱ͕Ͱ͖Δ 1IBTF 1IBTF 1IBTF 1IBTF
  8. { setHeader() } { getAuth(userID) } { logging(response) } {

    saveProfile( userID, profile ) } w 1JQFMJOF1IBTF͸طʹఆٛ͞Ε͍ͯΔ΋ͷ΋͋Ε͹
 ࣗ෼Ͱ৽͘͠೚ҙͷॱ൪Ͱ௥Ճ͢Δ͜ͱ΋Ͱ͖Δ
 ҎԼ͸1JQFMJOF1IBTFͷྫ 4FUVQ .POJUPSJOH $BMM 4FOE
  9. 4FUVQ $BMM 4FOE .POJUPSJOH %FGBVMU)FBEFS $BMM-PHHJOH 'FBUVSF 3PVUJOH JOTUBMM w

    1JQFMJOF1IBTF΁ͷॲཧͷׂΓ౰ͯ͸
 'FBUVSFͷJOTUBMM΍3PVUJOHͷఆٛʹΑͬͯߦΘΕΔ
 ˞ͻͱͭͷϑΣΠζʹෳ਺ͷॲཧΛׂΓ౰ͯΔ͜ͱ΋Մೳ
  10. 4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

    { saveProfile( userID, profile ) } w 1JQFMJOF1IBTF΁ͷॲཧͷׂΓ౰ͯ͸
 'FBUVSFͷJOTUBMM΍3PVUJOHͷఆٛʹΑͬͯߦΘΕΔ
  11. 4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } "QQMJDBUJPO$BMM w 1JQFMJOF1IBTFؒͰ͸"QQMJDBUJPO$BMMͱ͍͏
 ΞϓϦέʔγϣϯ΍ϦΫΤετɾϨεϙϯεʹؔ͢Δ৘ใΛ
 อ࣋ͨ͠NVUBCMFͳΦϒδΣΫτΛڞ༗͍ͯ͠Δ
  12. 4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) }
  13. 4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶃͰϦΫΤετΛϋϯυϦϯάͯ͠
 5ISFBEᶄ্ͰίϧʔνϯΛ։࢝
 ͦͷ··5ISFBEᶄ্ͷίϧʔνϯͰ1JQFMJOFΛ࣮ߦ
  14. 4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶃͷεϨου͸ϊϯϒϩοΩϯάঢ়ଶͳͷͰ
 ଞͷϦΫΤετΛ଴ͭ͜ͱ͕Ͱ͖Δ
  15. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕։࢝ { setHeader() } { getAuth(userID)

    } { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶄ্ͷίϧʔνϯ͕ผͷίϧʔνϯΛಉεϨουͰ։࢝ ᶃ4FUVQϑΣΠζʹׂΓ౰ͯΒΕͨϥϜμࣜΛ࣮ߦ
  16. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧ͕։࢝ { logging(response) } {

    saveProfile( userID, profile ) } { getAuth(userID) } { setHeader() } w ᶃ4FUVQϑΣΠζΛ࣮ߦ͢Δίϧʔνϯ͕׬ྃ
 ᶄ.POJUPSJOHϑΣΠζͷॲཧΛ࣮ߦ͢ΔผͷίϧʔνϯΛ։࢝
  17. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕։࢝ { setHeader() } { getAuth(userID)

    } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ ॲཧ͕ऴྃ w ᶄ.POJUPSJOHϑΣΠζΛ࣮ߦ͢Δίϧʔνϯ͕׬ྃ
 ᶅ$BMMϑΣΠζͰผͷॲཧΛ࣮ߦ͢ΔผͷίϧʔνϯΛ։࢝
  18. 4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕։࢝ w ᶅ$BMMϑΣΠζΛ࣮ߦ͢Δίϧʔνϯ͕׬ྃ
 ᶆ4FOEϑΣΠζͰผͷॲཧΛ࣮ߦ͢ΔผͷίϧʔνϯΛ։࢝
  19. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ { setHeader()

    } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } w 4FOEϑΣΠζͷॲཧ͕׬ྃͨ͠Β5ISFBEᶄ্ͷίϧʔνϯ͕ ऴྃ͠ɺݺͼग़͠ݩͷ5ISFBEᶃͷ໭ͬͯϋϯυϦϯά͕ऴྃ
  20. 4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶄ্Ͱ։࢝ͨ͠࠷ॳͷίϧʔνϯ͕
 ֤1JQFMJOF1IBTFຖʹ౎౓ίϧʔνϯΛੜ੒͍ͯ͠Δ
 ͦΕΒ͸શͯ5ISFBEᶄ্Ͱಈ࡞͢Δ ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%
  21. 4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) }
  22. 4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) }
  23. 4FUVQ $BMM 4FOE .POJUPSJOH { delay(1000L) } { logging(response) }

    { saveProfile( userID, profile ) } { getAuth(userID) } Ұ࣌தஅ͢Δؔ਺ 1 : suspendؔ਺ʹΑͬͯҰ࣌தஅ͢Δྫ
  24. 4FUVQ $BMM 4FOE .POJUPSJOH { delay(1000L) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶃͰϦΫΤετΛϋϯυϦϯάͯ͠
 5ISFBEᶄ্ͰίϧʔνϯΛ։࢝
 ͦͷ··5ISFBEᶄ্ͷίϧʔνϯͰ1JQFMJOFΛ࣮ߦ
  25. 4FUVQ $BMM 4FOE .POJUPSJOH w 5ISFBEᶄ্Ͱίϧʔνϯ͕4FUVQϑΣΠζͷॲཧΛ࣮ߦ ॲཧΛ࣮ߦ { delay(1000L) }

    { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) }
  26. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧΛ࣮ߦ { delay(1000L) } {

    logging(response) } { saveProfile( userID, profile ) } { getAuth(userID) } w 4FUVQϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ
 ίϧʔνϯ͕.POJUPSJOHϑΣΠζͷॲཧΛ࣮ߦ Ұ࣌தஅ͢Δؔ਺
  27. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࠶։ { delay(1000L) } { getAuth(userID)

    } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ w தஅॲཧ͕׬ྃͨ͠Β5ISFBEᶄͰ.POJUPSJOHϑΣΠζͷ
 ࢒ΓͷॲཧΛ࣮ߦ ҧ͏5ISFBEͷՄೳੑ͕͋Δ͜ͱʹ஫ҙ
  28. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { delay(1000L) } { getAuth(userID)

    } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ w .POJUPSJOHϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ
 ίϧʔνϯ͕$BMMϑΣΠζͷॲཧΛ࣮ߦ ॲཧ͕ऴྃ
  29. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { delay(1000L) } { getAuth(userID)

    } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ w $BMMϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ
 ίϧʔνϯ͕4FOEϑΣΠζͷॲཧΛ࣮ߦ
  30. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ { delay(1000L)

    } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } w 4FOEϑΣΠζͷॲཧ͕׬ྃͨ͠Β5ISFBEᶄ্ͷίϧʔνϯ͕ ऴྃ͠ɺݺͼग़͠ݩͷ5ISFBEᶃͷ໭ͬͯϋϯυϦϯά͕ऴྃ
  31. 4FUVQ $BMM 4FOE .POJUPSJOH { launch { delay(1000L) }
 logging(request)

    } { logging(response) } { saveProfile( userID, profile ) } { getAuth(userID) } ผεϨουͰ
 ॲཧΛߦ͏ϥϜμ 2 : launchؔ਺ͷྫ
  32. 4FUVQ $BMM 4FOE .POJUPSJOH { launch { delay(1000L) }
 logging(request)

    } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶃͰϦΫΤετΛϋϯυϦϯάͯ͠
 5ISFBEᶄ্ͰίϧʔνϯΛ։࢝
 ͦͷ··5ISFBEᶄ্ͷίϧʔνϯͰ1JQFMJOFΛ࣮ߦ
  33. 4FUVQ $BMM 4FOE .POJUPSJOH w 5ISFBEᶄ্Ͱίϧʔνϯ͕4FUVQϑΣΠζͷॲཧΛ࣮ߦ ॲཧΛ࣮ߦ { launch {

    delay(1000L) }
 logging(request) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) }
  34. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧΛ࣮ߦ { logging(response) } {

    saveProfile( userID, profile ) } { getAuth(userID) } w 4FUVQϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ
 ίϧʔνϯ͕.POJUPSJOHϑΣΠζͷॲཧΛ࣮ߦ { launch { delay(1000L) }
 logging(request) } ผεϨουͰ
 ॲཧΛߦ͏ϥϜμ
  35. 4FUVQ $BMM 4FOE .POJUPSJOH w MBVODIؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝
 5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ MBVODIؔ਺Λ࣮ߦ { getAuth(userID)

    } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ { launch { delay(1000L) }
 logging(request) } ผεϨουͰ
 ॲཧΛߦ͏ϥϜμ
  36. 4FUVQ $BMM 4FOE .POJUPSJOH w MBVODIؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝
 5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ { launch {

    delay(1000L) }
 logging(request) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ ࢒ΓͷॲཧΛ࣮ߦ 5ISFBEᶅͰ࣮ߦத ผεϨουͰ
 ॲཧΛߦ͏ϥϜμ
  37. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { launch { delay(1000L) }


    logging(request) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ w .POJUPSJOHϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ
 ίϧʔνϯ͕$BMMϑΣΠζͷॲཧΛ࣮ߦ ॲཧ͕ऴྃ 5ISFBEᶅͰ࣮ߦத
  38. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { launch { delay(1000L) }


    logging(request) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ w $BMMϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ
 ίϧʔνϯ͕4FOEϑΣΠζͷॲཧΛ࣮ߦ 5ISFBEᶅͰ࣮ߦத
  39. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ { launch

    { delay(1000L) }
 logging(request) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } w 4FOEϑΣΠζͷॲཧ͕׬ྃͨ͠Β5ISFBEᶄ্ͷίϧʔνϯ͸ 5ISFBEᶅͷίϧʔνϯ͕ऴྃ͢Δ·Ͱ଴ͭ 5ISFBEᶅͰ࣮ߦத
  40. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ { launch

    { delay(1000L) }
 logging(request) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } 5ISFBEᶅͰ
 ॲཧ͕ऴྃ w 5ISFBEᶅͷίϧʔνϯ͕ऴྃͨ͠Β5ISFBEᶄ্ͷίϧʔνϯ ͕ऴྃ͠ɺݺͼग़͠ݩͷ5ISFBEᶃͷ໭ͬͯϋϯυϦϯά͕ऴྃ
  41. 4FUVQ $BMM 4FOE .POJUPSJOH { async { delay(1000L)
 “Finish” }.await()

    } { logging(response) } { saveProfile( userID, profile ) } { getAuth(userID) } ผεϨουͰॲཧΛߦͬͯ
 ׬ྃΛ଴ͭϥϜμ 3 : asyncؔ਺ͷྫ
  42. 4FUVQ $BMM 4FOE .POJUPSJOH { async { delay(1000L)
 “Finish” }.await()

    } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶃͰϦΫΤετΛϋϯυϦϯάͯ͠
 5ISFBEᶄ্ͰίϧʔνϯΛ։࢝
 ͦͷ··5ISFBEᶄ্ͷίϧʔνϯͰ1JQFMJOFΛ࣮ߦ
  43. 4FUVQ $BMM 4FOE .POJUPSJOH w 5ISFBEᶄ্Ͱίϧʔνϯ͕4FUVQϑΣΠζͷॲཧΛ࣮ߦ ॲཧΛ࣮ߦ { async {

    delay(1000L)
 “Finish” }.await() } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) }
  44. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧΛ࣮ߦ { logging(response) } {

    saveProfile( userID, profile ) } { getAuth(userID) } w 4FUVQϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ
 ίϧʔνϯ͕.POJUPSJOHϑΣΠζͷॲཧΛ࣮ߦ { async { delay(1000L)
 “Finish” }.await() } ผεϨουͰॲཧΛߦͬͯ
 ׬ྃΛ଴ͭϥϜμ
  45. 4FUVQ $BMM 4FOE .POJUPSJOH w BTZODؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝
 5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ BTZODؔ਺Λ࣮ߦ { getAuth(userID)

    } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ { async { delay(1000L)
 “Finish” }.await() } ผεϨουͰॲཧΛߦͬͯ
 ׬ྃΛ଴ͭϥϜμ
  46. 4FUVQ $BMM 4FOE .POJUPSJOH w BTZODؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝
 5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ { async {

    delay(1000L)
 “Finish” }.await() } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ ࢒ΓͷॲཧΛ࣮ߦ ผεϨουͰॲཧΛߦͬͯ
 ׬ྃΛ଴ͭϥϜμ 5ISFBEᶅͰ࣮ߦத
  47. 4FUVQ $BMM 4FOE .POJUPSJOH { async { delay(1000L)
 “Finish” }.await()

    } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ 5ISFBEᶅ͕
 ऴΘΔ·Ͱ଴ػ 5ISFBEᶅͰ࣮ߦத ผεϨουͰॲཧΛߦͬͯ
 ׬ྃΛ଴ͭϥϜμ w 5ISFBEᶅ্ͷίϧʔνϯͷ׬ྃΛ଴ػ͍ͯ͠ΔͷͰ
 5ISFBEᶄͷ.POJUPSJOHϑΣΠζͷॲཧ΋׬ྃ͠ͳ͍··
  48. 4FUVQ $BMM 4FOE .POJUPSJOH { async { delay(1000L)
 “Finish” }.await()

    } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ ࢒ΓͷॲཧΛ࣮ߦ ผεϨουͰॲཧΛߦͬͯ
 ׬ྃΛ଴ͭϥϜμ w 5ISFBEᶅ্ͷίϧʔνϯͷ׬ྃͷ݁ՌΛड͚ͯ
 5ISFBEᶄͷ.POJUPSJOHϑΣΠζͷॲཧΛ࠶։ 5ISFBEᶅͰॲཧ͕ऴྃ
  49. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { async { delay(1000L)
 “Finish”

    }.await() } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ ॲཧ͕ऴྃ w 5ISFBEᶄͷ.POJUPSJOHϑΣΠζͷॲཧ͕ऴྃͯ͠
 ΍ͬͱ$BMMϑΣΠζͷ࣮ߦΛ։࢝Ͱ͖Δ 5ISFBEᶅͰॲཧ͕ऴྃ
  50. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { asyncFun(context) } { getAuth(userID)

    } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ ॲཧ͕ऴྃ w 5ISFBEᶄͷ.POJUPSJOHϑΣΠζͷॲཧ͕ऴྃͯ͠
 ΍ͬͱ$BMMϑΣΠζͷ࣮ߦΛ։࢝Ͱ͖Δ ͜ͷผεϨουͷॲཧ଴ͪͷ࣌ؒΛ
 ༗ޮʹ࢖͏ͨΊͷ"1*͕
 ,UPS͔Βఏڙ͞Ε͍ͯ·͢ʂ
  51. 4FUVQ $BMM 4FOE .POJUPSJOH { val id = async {

    delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { logging(response) } { saveProfile( userID, profile ) } { getAuth(userID) } QSPDFFE Λ࣮ߦ͢ΔϥϜμ 4 : proceedϝιουͱasyncؔ਺ͷྫ
  52. 4FUVQ $BMM 4FOE .POJUPSJOH { val id = async {

    delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } QSPDFFE Λ࣮ߦ͢ΔϥϜμ
  53. 4FUVQ $BMM 4FOE .POJUPSJOH { val id = async {

    delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶃͰϦΫΤετΛϋϯυϦϯάͯ͠
 5ISFBEᶄ্ͰίϧʔνϯΛ։࢝
 ͦͷ··5ISFBEᶄ্ͷίϧʔνϯͰ1JQFMJOFΛ࣮ߦ
  54. 4FUVQ $BMM 4FOE .POJUPSJOH w 5ISFBEᶄ্Ͱίϧʔνϯ͕4FUVQϑΣΠζͷॲཧΛ࣮ߦ ॲཧΛ࣮ߦ { val id

    = async { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) }
  55. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧΛ࣮ߦ { logging(response) } {

    saveProfile( userID, profile ) } { getAuth(userID) } w 4FUVQϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ
 ίϧʔνϯ͕.POJUPSJOHϑΣΠζͷॲཧΛ࣮ߦ { val id = async { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } QSPDFFE Λ࣮ߦ͢ΔϥϜμ
  56. 4FUVQ $BMM 4FOE .POJUPSJOH w BTZODؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝
 5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ BTZODؔ਺Λ࣮ߦ { getAuth(userID)

    } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ { val id = async { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) }
  57. 4FUVQ $BMM 4FOE .POJUPSJOH w BTZODؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝
 5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ { val id

    = async { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ ࢒ΓͷॲཧΛ࣮ߦ 5ISFBEᶅͰ࣮ߦத QSPDFFE Λ࣮ߦ͢ΔϥϜμ
  58. 4FUVQ $BMM 4FOE .POJUPSJOH { val id = async {

    delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ w 5ISFBEᶄ্ͰQSPDFFEΛ࣮ߦ͢Δͱ5ISFBEᶅ্ͷίϧʔνϯͷ ׬ྃΛ଴ͨͣʹ.POJUPSJOHϑΣΠζΛҰ࣌தஅͰ͖Δ ॲཧΛҰ࣌தஅ QSPDFFE Λ࣮ߦ͢ΔϥϜμ 5ISFBEᶅͰ࣮ߦத
  59. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { val id = async

    { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ w 5ISFBEᶄͷ.POJUPSJOHϑΣΠζΛҰ࣌தஅͯ͠
 ͦͷ··5ISFBEᶄ্Ͱ$BMMϑΣΠζͷ࣮ߦΛ։࢝ ॲཧΛҰ࣌தஅ 5ISFBEᶅͰ࣮ߦத
  60. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { val id = async

    { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ ॲཧ͕ऴྃ w $BMMϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ
 ίϧʔνϯ͕4FOEϑΣΠζͷॲཧΛ࣮ߦ ॲཧΛҰ࣌தஅ 5ISFBEᶅͰ࣮ߦத
  61. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { val id = async

    { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ ॲཧ͕ऴྃ w 5ISFBEᶄ্Ͱ4FOEϑΣΠζͷॲཧΛ࣮ߦ͍ͯ͠Δؒʹ
 5ISFBEᶅ্ͷίϧʔνϯͷॲཧ͕׬ྃ ॲཧΛҰ࣌தஅ 5ISFBEᶅͰॲཧ͕ऴྃ
  62. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ { val id

    = async { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } w 4FOEϑΣΠζͷॲཧ͕׬ྃͨ͠Β5ISFBEᶄ্ͷίϧʔνϯ͸
 .POJUPSJOHϑΣΠζͷॲཧΛ࠶։͢Δ ॲཧΛ࠶։ 5ISFBEᶅͰॲཧ͕ऴྃ
  63. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ { val id

    = async { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } w 4FOEϑΣΠζͷॲཧ͕׬ྃͨ͠Β5ISFBEᶄ্ͷίϧʔνϯ͸
 .POJUPSJOHϑΣΠζͷॲཧΛ࠶։͢Δ ࢒ΓͷॲཧΛ࣮ߦ 5ISFBEᶅͰॲཧ͕ऴྃ
  64. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ { val

    id = async { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶄ্ͷίϧʔνϯ͕ऴྃͨ͠Β
 ݺͼग़͠ݩͷ5ISFBEᶃͷ໭ͬͯϋϯυϦϯά͕ऴྃ 5ISFBEᶅͰॲཧ͕ऴྃ
  65. Continuation (ܧଓ) w TVTQFOEؔ਺Ͱதஅ͞Εͨίϧʔνϯͷঢ়ଶ w தஅ͞Εͨ෦෼Ҏ߱ͷ࢒Γͷॲཧ ίʔϧόοΫ Λද͢ w SFTVNF8JUIϝιου͸׬ྃίʔϧόοΫͰ͋Γ


    ίϧʔνϯͷ׬ྃ࣌ʹ੒ޭɾࣦഊͷ͍ͣΕ͔Λฦ͢ public interface Continuation<in T> { public val context: CoroutineContext public fun resumeWith(result: Result<T>) }
  66. suspendؔ਺ suspend fun susFuncA() { delay(1000L) } val block: suspend

    () -> Unit = {} w ؔ਺಺ͰଞͷTVTQFOEؔ਺Λݺͼग़͢͜ͱͰ
 ࣮ߦεϨουΛϒϩοΫͤͣʹ
 ίʔυ࣮ߦΛதஅ͢ΔՄೳੑͷ͋Δؔ਺ w TVTQFOEؔ਺͸ଞͷTVTQFOEؔ਺͔ΒͷΈݺͼग़͢͜ͱ͕Մೳ TVTQFOEؔ਺ϥϜμ fun normalFunc() { susFuncA(1000L) } ௨ৗͷؔ਺͔Βͷݺͼग़͠
  67. suspendؔ਺ suspend fun susFuncA() { delay(1000L) } val block: suspend

    () -> Unit = {} w ؔ਺಺ͰଞͷTVTQFOEؔ਺Λݺͼग़͢͜ͱͰ
 ࣮ߦεϨουΛϒϩοΫͤͣʹ
 ίʔυ࣮ߦΛதஅ͢ΔՄೳੑͷ͋Δؔ਺ w TVTQFOEؔ਺͸ଞͷTVTQFOEؔ਺͔ΒͷΈݺͼग़͢͜ͱ͕Մೳ TVTQFOEؔ਺ϥϜμ fun normalFunc() { susFuncA(1000L) } ௨ৗͷؔ਺͔Βͷݺͼग़͠ ͳͥTVTQFOEؔ਺͸
 ௨ৗͷؔ਺͔Βݺͼग़͢͜ͱ͕ग़དྷͳ͍ͷ͔ʁ
  68. suspendؔ਺ suspend fun susFunc( time: Long ) : String TVTQFOEؔ਺

    fun susFunc( time: Long, continuation: Continuation ) : Any? ੜ੒͞ΕΔίʔυ ٙࣅίʔυ w TVTQFOEम০ࢠ͸ίϯύΠϧ࣌ʹผͷؔ਺ʹม׵͞ΕΔ ˞࣮ࡍ͸TVTQFOEؔ਺಺ͷίʔυ΋γάχνϟ͕มߋ͞ΕͨΓ
 ঢ়ଶΫϥε͕ੜ੒͞ΕͨΓ͍ͯ͠Δ఺ʹ஫ҙɻ
  69. suspend fun susFunc( time: Long ) : String { delay(time)

    return "Kotlin Fest!" } TVTQFOEؔ਺
  70. suspend fun susFunc( time: Long, continuation: Continuation ) : Any?

    { val call_back = when(continuation){ is ... -> continuation else -> ... } when(call_back.lable){ 1 -> { call_back.lable = 2 return delay(time, call_back) } 2 -> { return "Kotlin Fest!" } } } suspend fun susFunc( time: Long ) : String { delay(time) return "Kotlin Fest!" } TVTQFOEؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ
  71. (suspend) fun susFunc( time: Long, continuation: Continuation ) : Any?

    { val call_back = when(continuation){ is ... -> continuation else -> ... } when(call_back.lable){ 1 -> { call_back.lable = 2 return delay(time, call_back) } 2 -> { return "Kotlin Fest!" } } } suspend fun susFunc( time: Long ) : String { delay(time) return "Kotlin Fest!" } TVTQFOEؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ
  72. (suspend) fun susFunc( time: Long, continuation: Continuation ) : Any?

    { val call_back = when(continuation){ is ... -> continuation else -> ... } when(call_back.lable){ 1 -> { call_back.lable = 2 return delay(time, call_back) } 2 -> { return "Kotlin Fest!" } } } suspend fun susFunc( time: Long ) : String { delay(time) return "Kotlin Fest!" } TVTQFOEؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ ᶃҾ਺ʹ$POUJOVBUJPO͕௥Ճ͞Ε͍ͯΔ
 ᶄฦΓ஋͕"OZ ܕʹͳ͍ͬͯΔ
  73. (suspend) fun susFunc( time: Long, continuation: Continuation ) : Any?

    { val call_back = when(continuation){ is ... -> continuation else -> ... } when(call_back.lable){ 1 -> { call_back.lable = 2 return delay(time, call_back) } 2 -> { return "Kotlin Fest!" } } } suspend fun susFunc( time: Long ) : String { delay(time) return "Kotlin Fest!" } TVTQFOEؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ ᶅ಺෦Ͱݺͼग़͍ͯ͠ΔTVTQFOEؔ਺ͷҾ਺ʹ΋ $POUJOVBUJPO͕௥Ճ͞Ε͍ͯͯ
 ࣗ਎͕ड͚औͬͨ$POUJOVBUJPOΛ౉͍ͯ͠Δ
  74. (suspend) fun susFunc( time: Long, continuation: Continuation ) : Any?

    { val call_back = when(continuation){ is ... -> continuation else -> ... } when(call_back.lable){ 1 -> { call_back.lable = 2 return delay(time, call_back) } 2 -> { return "Kotlin Fest!" } } } suspend fun susFunc( time: Long ) : String { delay(time) return "Kotlin Fest!" } TVTQFOEؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ ௨ৗͷؔ਺͔ΒTVTQFOEؔ਺Λݺͼग़ͦ͏ͱͯ͠΋
 $POUJOVBUJPOΛҾ਺ͱͯ͠౉͢͜ͱ͕Ͱ͖ͳ͍
  75. (suspend) fun susFunc( time: Long, continuation: Continuation ) : Any?

    { val call_back = when(continuation){ is ... -> continuation else -> ... } when(call_back.lable){ 1 -> { call_back.lable = 2 return delay(time, call_back) } 2 -> { return "Kotlin Fest!" } } } suspend fun susFunc( time: Long ) : String { delay(time) return "Kotlin Fest!" } TVTQFOEؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ
  76. (suspend) fun susFunc( time: Long, continuation: Continuation ) : Any?

    { val call_back = when(continuation){ is ... -> continuation else -> ... } when(call_back.lable){ 1 -> { call_back.lable = 2 return delay(time, call_back) } 2 -> { return "Kotlin Fest!" } } } suspend fun susFunc( time: Long ) : String { delay(time) return "Kotlin Fest!" } TVTQFOEؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ Ͱ͸Ͳ͏΍ͬͯ࠷ॳͷTVTQFOEؔ਺Λ
 ී௨ͷؔ਺͔Βݺͼग़͢ʁ
 ίϧʔνϯΛ։࢝͢Δʁ
  77. val continuation = object : Continuation<Unit> { override val context:

    CoroutineContext = EmptyCoroutineContext override fun resumeWith(result: Result<Unit>){ ɾɾɾ } } suspend { delay(1000L) }.startCoroutine(continuation) w TVTQFOEϥϜμͷ֦ுؔ਺ͱͯ͠ఆٛ͞Ε͍ͯͯ
 TVTQFOEؔ਺Ҏ֎ͷ௨ৗͷؔ਺͔Β΋ݺͼग़͕͠Մೳ w $POUJOVBUJPO͸ࣗલͰ༻ҙ͢Δ͔
 طʹ։͍࢝ͯ͠Δίϧʔνϯ͔Βऔಘ͢Δ
  78. val continuation = object : Continuation<Unit> { override val context:

    CoroutineContext = EmptyCoroutineContext override fun resumeWith(result: Result<Unit>){ ɾɾɾ } } suspend { delay(1000L) }.startCoroutine(continuation) w TVTQFOEϥϜμͷ֦ுؔ਺ͱͯ͠ఆٛ͞Ε͍ͯͯ
 TVTQFOEؔ਺Ҏ֎ͷ௨ৗͷؔ਺͔Β΋ݺͼग़͕͠Մೳ w $POUJOVBUJPO͸ࣗલͰ༻ҙ͢Δ͔
 طʹ։͍࢝ͯ͠Δίϧʔνϯ͔Βऔಘ͢Δ
  79. inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrReturn( completion: Continuation<T> ):

    Any? = (this as Function1<Continuation<T>, Any?>).invoke(completion) public fun <T> (suspend () -> T).startCoroutine( completion: kotlin.coroutines.Continuation<T> ): kotlin.Unit { /* compiled code */ } startCoroutineUninterceptedOrReturn w TUBSU$PSPVUJOFͱҧ͍ɺฦΓ஋Λड͚औΔ w ࣮ߦͨ͠TVTQFOEؔ਺͕಺෦ͷதஅ఺Ͱதஅ͞ΕΔͱ
 $03065*/&@4641&/%&%ϚʔΧʔΛฦ͢
  80. inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrReturn( completion: Continuation<T> ):

    Any? = (this as Function1<Continuation<T>, Any?>).invoke(completion) public fun <T> (suspend () -> T).startCoroutine( completion: kotlin.coroutines.Continuation<T> ): kotlin.Unit { /* compiled code */ } startCoroutineUninterceptedOrReturn w TUBSU$PSPVUJOFͱҧ͍ɺฦΓ஋Λड͚औΔ w ࣮ߦͨ͠TVTQFOEؔ਺͕಺෦ͷதஅ఺Ͱதஅ͞ΕΔͱ
 $03065*/&@4641&/%&%ϚʔΧʔΛฦ͢
  81. inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrReturn( completion: Continuation<T> ):

    Any? = (this as Function1<Continuation<T>, Any?>).invoke(completion) internal enum class CoroutineSingletons { COROUTINE_SUSPENDED, UNDECIDED, RESUMED } startCoroutineUninterceptedOrReturn w TUBSU$PSPVUJOFͱҧ͍ɺฦΓ஋Λड͚औΔ w ࣮ߦͨ͠TVTQFOEؔ਺͕಺෦ͷதஅ఺Ͱதஅ͞ΕΔͱ
 $03065*/&@4641&/%&%ϚʔΧʔΛฦ͢
  82. inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrReturn( completion: Continuation<T> ):

    kotlin.Any? { /* compiled code */ } internal enum class CoroutineSingletons { COROUTINE_SUSPENDED, UNDECIDED, RESUMED } startCoroutineUninterceptedOrReturn w TUBSU$PSPVUJOFͱҧ͍ɺฦΓ஋Λड͚औΔ w ࣮ߦͨ͠TVTQFOEؔ਺͕಺෦ͷதஅ఺Ͱதஅ͞ΕΔͱ
 $03065*/&@4641&/%&%ϚʔΧʔΛฦ͢ ίϧʔνϯʹ౉͞Ε͍ͯΔ
 Continuation͸Ͳ͏΍ͬͯऔಘͰ͖Δʁ
  83. w ίϧʔνϯΛதஅঢ়ଶͱͯ͠ҡ࣋͢Δ৔߹
 $03065*/&@4641&/%&%ϚʔΧʔΛฦ͢ w ίϧʔνϯΛ׬ྃ͢Δ৔߹
 ݁ՌΛSFTVNF8JUIϝιουʹ౉࣮ͯ͠ߦ suspend inline fun <T>

    suspendCoroutineUninterceptedOrReturn( crossinline block: (Continuation<T>) -> Any? ): T suspendCoroutineUninterceptedOrReturn
  84. 4FUVQ $BMM 4FOE .POJUPSJOH { delay(1000L) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶄ্Ͱ։࢝ͨ͠࠷ॳͷίϧʔνϯ͕
 ֤1JQFMJOF1IBTFຖʹ౎౓ίϧʔνϯΛੜ੒͍ͯ͠Δ
 ͦΕΒ͸શͯ5ISFBEᶄ্Ͱಈ࡞͢Δ ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%
  85. 4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶄ্Ͱ։࢝ͨ͠࠷ॳͷίϧʔνϯ͕
 ֤1JQFMJOF1IBTFຖʹ౎౓ίϧʔνϯΛੜ੒͍ͯ͠Δ
 ͦΕΒ͸શͯ5ISFBEᶄ্Ͱಈ࡞͢Δ ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ% 1IBTFຖʹίϧʔνϯΛ
 ੜ੒͢Δ͜ͱʹΑͬͯ
 1IBTFຖʹதஅॲཧ΍ΩϟϯηϧΛ
 ੍ޚ͢Δ͜ͱ͕Ͱ͖Δ
  86. 4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶄ্Ͱ։࢝ͨ͠࠷ॳͷίϧʔνϯ͕
 ֤1JQFMJOF1IBTFຖʹ౎౓ίϧʔνϯΛੜ੒͢Δ͍ͯ͠Δ
 ͦΕΒ͸શͯ5ISFBEᶄ্Ͱಈ࡞͢Δ ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ% ܰྔͱ͸͍͑
 ϦΫΤετͷ౓ʹେྔʹ
 ίϧʔνϯΛੜ੒͍ͯͯ͠
 ύϑΥʔϚϯεʹӨڹ͸ͳ͍ͷʁ
  87. 4FUVQ $BMM 4FOE .POJUPSJOH { delay(1000L) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶄ্Ͱ։࢝ͨ͠࠷ॳͷίϧʔνϯ͕
 ֤1JQFMJOF1IBTFຖʹ౎౓ίϧʔνϯΛੜ੒͍ͯ͠Δ
 ͦΕΒ͸શͯ5ISFBEᶄ্Ͱಈ࡞͢Δ ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%
  88. 4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w ࠷ॳͷίϧʔνϯ͸֤1IBTFίϧʔνϯΛ࡞੒͢Δࡍʹ
 ৽ͨʹ$POUJOVBUJPOΛ࡞Βͣɺࣗ਎ͷ$POUJOVBUJPOΛ
 Ҿ͖౉͍ͯ͠Δ ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%
  89. 4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ% suspend inline fun <T> suspendCoroutineUninterceptedOrReturn( crossinline block: (Continuation<T>) -> Any? ): T w TVTQFOE$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOؔ਺Λ࢖͏ͱ
 ࣮ߦதͷίϧʔνϯͷ$POUJOVBUJPOΛऔΓग़ͯ͠
 Ҿ਺ͷϥϜμࣜͷதͰѻ͏͜ͱ͕Ͱ͖Δ
  90. 4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w TVTQFOE$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOؔ਺Λ࢖͏ͱ
 ࣮ߦதͷίϧʔνϯͷ$POUJOVBUJPOΛऔΓग़ͯ͠
 Ҿ਺ͷϥϜμࣜͷதͰѻ͏͜ͱ͕Ͱ͖Δ ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ% suspend inline fun <T> suspendCoroutineUninterceptedOrReturn( crossinline block: (Continuation<T>) -> Any? ): T
  91. 4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOؔ਺ͷҾ਺ʹ
 $POUJOVBUJPOΛ౉͢ͱ৽ͨʹ$POUJOVBUJPOΛ
 ࡞੒ͤͣʹίϧʔνϯΛ։࢝Ͱ͖Δ ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ% inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrReturn( completion: Continuation<T> ): kotlin.Any?
  92. 4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ% inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrReturn( completion: Continuation<T> ): kotlin.Any? w TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOؔ਺ͷҾ਺ʹ
 $POUJOVBUJPOΛ౉͢ͱ৽ͨʹ$POUJOVBUJPOΛ
 ࡞੒ͤͣʹίϧʔνϯΛ։࢝Ͱ͖Δ
  93. suspendCoroutineUninterceptedOrReturn { continuation -> do { val rc = PhaseʹׂΓ౰ͯΒΕͨϥϜμࣜ.

    startCoroutineUninterceptedOrReturn(ɾɾɾ) ɾɾɾ } while (true) COROUTINE_SUSPENDED } w TVTQFOE$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOͱ
 TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOΛ૊Έ߹ΘͤΔ͜ͱͰ
 $POUJOVBUJPOΛڞ༗͠ͳ͕ΒίϧʔνϯΛ࡞੒͍ͯ͠Δ
  94. 4FUVQ $BMM 4FOE .POJUPSJOH { delay(1000L) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w $POUJOVBUJPOΛڞ༗ͯ͠ίϧʔνϯͷੜ੒ίετΛ཈͑Δ͜ͱͰ
 ύΠϓϥΠϯͷ࣮ߦ଎౓ͷύϑΥʔϚϯεΛ޲্͍ͯ͠Δ ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%
  95. 4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w $POUJOVBUJPOΛڞ༗ͯ͠ίϧʔνϯͷੜ੒ίετΛ཈͑Δ͜ͱͰ
 ύΠϓϥΠϯͷ࣮ߦ଎౓ͷύϑΥʔϚϯεΛ޲্͍ͯ͠Δ ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ% TVTQFOE$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOͱ
 TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOΛ
 ૊Έ߹ΘͤͰίϧʔνϯͷੜ੒ίετΛ཈͑Δํ๏͸
 (FOFSBUPSTͷZJFMEؔ਺ͷ಺෦࣮૷Ͱ΋࢖ΘΕ͍ͯΔ
  96. proceedؔ਺ͷ࣮૷ 4FUVQ $BMM 4FOE .POJUPSJOH { val id = async

    { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } QSPDFFE Λ࣮ߦ͢ΔϥϜμ
  97. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { val id = async

    { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ w QSPDFFEϝιουΛ࣮ߦ͢Δͱ֘౰ϑΣΠζͷॲཧΛதஅͯ͠
 ޙଓͷύΠϓϥΠϯͷॲཧΛ࣮ߦͰ͖Δ ॲཧΛҰ࣌தஅ 5ISFBEᶅͰ࣮ߦத
  98. suspendCoroutineUninterceptedOrReturn { continuation -> do { ɾɾɾ val rc =

    PhaseʹׂΓ౰ͯΒΕͨϥϜμࣜ. startCoroutineUninterceptedOrReturn(ɾɾɾ) ɾɾɾ } while (true) COROUTINE_SUSPENDED } w QSPDFFEϝιουΛ࣮ߦ͢Δͱ$POUJOVBUJPOΛ৽ͨʹ࡞੒ͯ͠
 ผεϨουͰಈ࡞͢ΔίϧʔνϯΛ։࢝͢Δ
  99. private val continuation: Continuation<Unit> = object : Continuation<Unit>, CoroutineStackFrame {

    ɾɾɾ override val context: CoroutineContext get () { val cont = rootContinuation return when (cont) { null -> throw IllegalStateException("Not started") is Continuation<*> -> cont.context is List<*> -> (cont as List<Continuation<*>>).last().context else -> throw IllegalStateException("e") } } }
  100. private val continuation: Continuation<Unit> = object : Continuation<Unit>, CoroutineStackFrame {

    ɾɾɾ override val context: CoroutineContext get () { val cont = rootContinuation return when (cont) { null -> throw IllegalStateException("Not started") is Continuation<*> -> cont.context is List<*> -> (cont as List<Continuation<*>>).last().context else -> throw IllegalStateException("e") } } }
  101. ಠࣗͷCoroutineStart 4FUVQ $BMM 4FOE .POJUPSJOH { delay(1000L) } { delay(1000L)

    } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) }
  102. 4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w ΞϓϦέʔγϣϯ΍ϦΫΤετɺϨεϙϯεͷ৘ใΛ
 ϛϡʔλϒϧʹอ࣋ͨ͠"QQMJDBUJPO$BMMΦϒδΣΫτΛ
 ֤1JQFMJOF1IBTFؒͰڞ༗͍ͯ͠Δ { asyncFun(context) } { getAuth(userID) } { saveProfile( userID, profile ) } "QQMJDBUJPO$BMM
  103. 4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w "QQMJDBUJPO$BMM͸ύΠϓϥΠϯ಺ʹάϩʔόϧͳม਺ͱͯ͠
 ڞ༗͞ΕΔͷͰ͸ͳ͘ɺ1JQFMJOF1IBTFຖͷίϧʔνϯੜ੒࣌ʹ
 $POUJOVBUJPOͱҰॹʹҾ͖౉͍ͯ͠Δ "QQMJDBUJPO$BMM
  104. 4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w "QQMJDBUJPO$BMM͸ύΠϓϥΠϯ಺ʹάϩʔόϧͳม਺ͱͯ͠
 ڞ༗͞ΕΔͷͰ͸ͳ͘ɺ1JQFMJOF1IBTFຖͷίϧʔνϯੜ੒࣌ʹ
 $POUJOVBUJPOͱҰॹʹҾ͖౉͍ͯ͠Δ "QQMJDBUJPO$BMM ίϧʔνϯΛ։࢝͢Δͱ͖ʹ
 $POUJOVBUJPOҎ֎ͷΦϒδΣΫτΛ
 Ͳ͏΍ͬͯ౉͢ͷ͔ʁ
  105. public inline fun <T> (suspend () -> T). startCoroutineUninterceptedOrReturn( completion:

    kotlin.coroutines.Continuation<T> ): kotlin.Any? { /* compiled code */ } public inline fun <R, T> (suspend R.() -> T). startCoroutineUninterceptedOrReturn( receiver: R, completion: kotlin.coroutines.Continuation<T> ): kotlin.Any? { /* compiled code */ } w TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOΛ࢖͏ͱ
 ৽ͨʹίϧʔνϯΛੜ੒͢Δͱ͖ʹ$POUJOVBUJPOΛҾ਺ͱͯ͠
 ౉͢͜ͱͰίϧʔνϯؒͰ$POUJOVBUJPOΛڞ༗Ͱ͖Δ
  106. public inline fun <T> (suspend () -> T). startCoroutineUninterceptedOrReturn( completion:

    kotlin.coroutines.Continuation<T> ): kotlin.Any? { /* compiled code */ } public inline fun <R, T> (suspend R.() -> T). startCoroutineUninterceptedOrReturn( receiver: R, completion: kotlin.coroutines.Continuation<T> ): kotlin.Any? { /* compiled code */ } w $POUJOVBUJPOΛίϧʔνϯʹ౉͢"1*͔͠ެ։͞Ε͍ͯͳ͍
 ͦͷͨΊίϧʔνϯ։࢝࣌ʹ"QQMJDBUJPO$BMM΋Ҿ͖౉͢͜ͱ͸
 ௨ৗ͸ෆՄೳ
  107. internal actual inline fun <R, A> (suspend R.(A) -> Unit).startCoroutineUninterceptedOrReturn3(

    receiver: R, arg: A, continuation: Continuation<Unit> ): Any? { val function = (this as Function3<R, A, Continuation<Unit>, Any?>) return function.invoke(receiver, arg, continuation) } w ,UPSͰ͸$POUJOVBUJPOʹՃ͑ͯ೚ҙͷܕͷΦϒδΣΫτΛ
 Ҿ͖౉ͯ͠৽ͨʹίϧʔνϯΛ։࢝͢Δؔ਺Λಠ࣮ࣗ૷͍ͯ͠Δ w ૊ΈࠐΈؔ਺ͱ͍ۙॲཧΛҎԼͷؔ਺Ͱ࣮ݱ͍ͯ͠Δ
  108. public inline fun <R, T> (suspend R.() -> T). startCoroutineUninterceptedOrReturn(

    receiver: R, completion: kotlin.coroutines.Continuation<T> ): kotlin.Any? { /* compiled code */ } internal actual inline fun <R, A> (suspend R.(A) -> Unit).startCoroutineUninterceptedOrReturn3( receiver: R, arg: A, continuation: Continuation<Unit> ): Any? { val function = (this as Function3<R, A, Continuation<Unit>, Any?>) return function.invoke(receiver, arg, continuation) } ϥΠϒϥϦ͔Βఏڙ͞Ε͍ͯΔؔ਺ ,UPSͰಠ࣮ࣗ૷͍ͯ͠Δίϧʔνϯ։࢝"1*
  109. public inline fun <R, T> (suspend R.() -> T). startCoroutineUninterceptedOrReturn(

    receiver: R, completion: kotlin.coroutines.Continuation<T> ): kotlin.Any? { /* compiled code */ } internal actual inline fun <R, A> (suspend R.(A) -> Unit).startCoroutineUninterceptedOrReturn3( receiver: R, arg: A, continuation: Continuation<Unit> ): Any? { val function = (this as Function3<R, A, Continuation<Unit>, Any?>) return function.invoke(receiver, arg, continuation) } ,UPSͰಠ࣮ࣗ૷͍ͯ͠Δίϧʔνϯ։࢝"1* ϥΠϒϥϦ͔Βఏڙ͞Ε͍ͯΔؔ਺
  110. internal actual inline fun <R, A> (suspend R.(A) -> Unit).startCoroutineUninterceptedOrReturn3(

    receiver: R, arg: A, continuation: Continuation<Unit> ): Any? { val function = (this as Function3<R, A, Continuation<Unit>, Any?>) return function.invoke(receiver, arg, continuation) } w Ҿ਺Λ"ܕ͔͠ड͚औΒͳ͍͸ͣͷϥϜμࣜ UIJT ͕Կނ͔
 Ҿ਺ͱͯ͠"ܕɾ$POUJOVBUJPOͷ̎ͭΛड͚औΔ'VODUJPOܕʹ
 Ωϟετ͞Ε͔ͯΒ࣮ߦ͞Ε͍ͯΔ
  111. internal actual inline fun <R, A> ((suspend) R.(A, Continuation<Unit>) ->

    Unit). startCoroutineUninterceptedOrReturn3( receiver: R, arg: A, continuation: Continuation<Unit> ): Any? { val function = (this as Function3<R, A, Continuation<Unit>, Any?>) return function.invoke(receiver, arg, continuation) } w ࣮͸ϥϜμࣜ UIJT ͸TVTQFOEϥϜμͳͷͰίϯύΠϧ࣌ʹ͸
 Ҿ਺ͱͯ͠$POUJOVBUJPO΋ड͚औΔϥϜμࣜʹม׵͞ΕΔʂ w ͕࣮ͨͬͯ͠ߦ࣌ͷΩϟετ͸੒ޭ͢Δ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ
  112. internal actual inline fun <R, A> ((suspend) R.(A, Continuation<Unit>) ->

    Unit). startCoroutineUninterceptedOrReturn3( receiver: R, arg: A, continuation: Continuation<Unit> ): Any? { val function = (this as Function3<R, A, Continuation<Unit>, Any?>) return function.invoke(receiver, arg, continuation) } w ࣮͸ϥϜμࣜ UIJT ͸TVTQFOEϥϜμͳͷͰίϯύΠϧ࣌ʹ͸
 Ҿ਺ͱͯ͠$POUJOVBUJPO΋ड͚औΔϥϜμࣜʹม׵͞ΕΔʂ w ͕࣮ͨͬͯ͠ߦ࣌ͷΩϟετ͸੒ޭ͢Δ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ ίϯύΠϧޙͷίʔυͷγάωνϟΛ
 ༧ଌͯ͠ڧ੍Ωϟετ͍ͤͯ͞Δ
  113. internal actual inline fun <R, A> ((suspend) R.(A, Continuation<Unit>) ->

    Unit). startCoroutineUninterceptedOrReturn3( receiver: R, arg: A, continuation: Continuation<Unit> ): Any? { val function = (this as Function3<R, A, Continuation<Unit>, Any?>) return function.invoke(receiver, arg, continuation) } w ࣮͸ϥϜμࣜ UIJT ͸TVTQFOEϥϜμͳͷͰίϯύΠϧ࣌ʹ͸
 Ҿ਺ͱͯ͠$POUJOVBUJPO΋ड͚औΔϥϜμࣜʹม׵͞ΕΔʂ w ͕࣮ͨͬͯ͠ߦ࣌ͷΩϟετ͸੒ޭ͢Δ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ ࣮͸TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOͷ
 ࣮૷Ͱಉ͜͡ͱ͕ߦΘΕ͍ͯΔ
 
 ͜ͷํ๏Λࢀߟʹ͢Δͱ
 ೚ҙͷ਺ͷҾ਺Λίϧʔνϯ։࢝࣌ʹ
 ౉͢Α͏ͳ௿Ϩϕϧ"1*Λ
 ࣗ෼Ͱ࣮૷͢Δ͜ͱ͕Ͱ͖Δ
  114. 4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) }