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

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

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

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

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 ) }