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

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

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

45006d6f0db085781edc3cca26e98ce2?s=128

Yuji Koyano

August 24, 2019
Tweet

Transcript

  1. 8.
  2. 12.
  3. 20.

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

    Fest 2019!” } } } } Featureͷinstallྫ w จࣈྻΛฦ͢࠷খͷΞϓϦέʔγϣϯͷίʔυ
  4. 21.

    fun Application.main() { install(DefaultHeaders) install(CallLogging) routing { get("/kotline_fest") { call.respondText

    { "Kotlin Fest 2019!” } } } } Featureͷinstallྫ w JOTUBMMϝιουΛ࢖༻ͯ͠ΞϓϦέʔγϣϯʹػೳ௥Ճ
  5. 23.

    1IBTF 1IBTF 1IBTF 1IBTF { setHeader() } { getAuth(userID) }

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

    { setHeader() } { getAuth(userID) } { logging(response) } {

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

    { 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) { ɹɹɹɹɹɹɹɾɾɾ } }
  8. 26.

    { 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) { ɹɹɹɹɹɹɹɾɾɾ } }
  9. 27.

    { setHeader() } { getAuth(userID) } { logging(response) } {

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

    { setHeader() } { getAuth(userID) } { logging(response) } {

    saveProfile( userID, profile ) } w 1JQFMJOF1IBTF͸طʹఆٛ͞Ε͍ͯΔ΋ͷ΋͋Ε͹
 ࣗ෼Ͱ৽͘͠೚ҙͷॱ൪Ͱ௥Ճ͢Δ͜ͱ΋Ͱ͖Δ
 ҎԼ͸1JQFMJOF1IBTFͷྫ 4FUVQ .POJUPSJOH $BMM 4FOE
  11. 30.

    4FUVQ $BMM 4FOE .POJUPSJOH %FGBVMU)FBEFS $BMM-PHHJOH 'FBUVSF 3PVUJOH JOTUBMM w

    1JQFMJOF1IBTF΁ͷॲཧͷׂΓ౰ͯ͸
 'FBUVSFͷJOTUBMM΍3PVUJOHͷఆٛʹΑͬͯߦΘΕΔ
 ˞ͻͱͭͷϑΣΠζʹෳ਺ͷॲཧΛׂΓ౰ͯΔ͜ͱ΋Մೳ
  12. 31.

    4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

    { saveProfile( userID, profile ) } w 1JQFMJOF1IBTF΁ͷॲཧͷׂΓ౰ͯ͸
 'FBUVSFͷJOTUBMM΍3PVUJOHͷఆٛʹΑͬͯߦΘΕΔ
  13. 32.

    4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

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

    4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) }
  15. 34.

    4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶃͰϦΫΤετΛϋϯυϦϯάͯ͠
 5ISFBEᶄ্ͰίϧʔνϯΛ։࢝
 ͦͷ··5ISFBEᶄ্ͷίϧʔνϯͰ1JQFMJOFΛ࣮ߦ
  16. 35.

    4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶃͷεϨου͸ϊϯϒϩοΩϯάঢ়ଶͳͷͰ
 ଞͷϦΫΤετΛ଴ͭ͜ͱ͕Ͱ͖Δ
  17. 36.

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕։࢝ { setHeader() } { getAuth(userID)

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

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧ͕։࢝ { logging(response) } {

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

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕։࢝ { setHeader() } { getAuth(userID)

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

    4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

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

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ { setHeader()

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

    4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

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

    4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) }
  24. 47.

    4FUVQ $BMM 4FOE .POJUPSJOH { setHeader() } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) }
  25. 48.

    4FUVQ $BMM 4FOE .POJUPSJOH { delay(1000L) } { logging(response) }

    { saveProfile( userID, profile ) } { getAuth(userID) } Ұ࣌தஅ͢Δؔ਺ 1 : suspendؔ਺ʹΑͬͯҰ࣌தஅ͢Δྫ
  26. 49.

    4FUVQ $BMM 4FOE .POJUPSJOH { delay(1000L) } { getAuth(userID) }

    { logging(response) } { saveProfile( userID, profile ) } w 5ISFBEᶃͰϦΫΤετΛϋϯυϦϯάͯ͠
 5ISFBEᶄ্ͰίϧʔνϯΛ։࢝
 ͦͷ··5ISFBEᶄ্ͷίϧʔνϯͰ1JQFMJOFΛ࣮ߦ
  27. 50.

    4FUVQ $BMM 4FOE .POJUPSJOH w 5ISFBEᶄ্Ͱίϧʔνϯ͕4FUVQϑΣΠζͷॲཧΛ࣮ߦ ॲཧΛ࣮ߦ { delay(1000L) }

    { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) }
  28. 51.

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧΛ࣮ߦ { delay(1000L) } {

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

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࠶։ { delay(1000L) } { getAuth(userID)

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

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { delay(1000L) } { getAuth(userID)

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

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { delay(1000L) } { getAuth(userID)

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

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ { delay(1000L)

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

    4FUVQ $BMM 4FOE .POJUPSJOH { launch { delay(1000L) }
 logging(request)

    } { logging(response) } { saveProfile( userID, profile ) } { getAuth(userID) } ผεϨουͰ
 ॲཧΛߦ͏ϥϜμ 2 : launchؔ਺ͷྫ
  34. 59.

    4FUVQ $BMM 4FOE .POJUPSJOH { launch { delay(1000L) }
 logging(request)

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

    4FUVQ $BMM 4FOE .POJUPSJOH w 5ISFBEᶄ্Ͱίϧʔνϯ͕4FUVQϑΣΠζͷॲཧΛ࣮ߦ ॲཧΛ࣮ߦ { launch {

    delay(1000L) }
 logging(request) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) }
  36. 61.

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧΛ࣮ߦ { logging(response) } {

    saveProfile( userID, profile ) } { getAuth(userID) } w 4FUVQϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ
 ίϧʔνϯ͕.POJUPSJOHϑΣΠζͷॲཧΛ࣮ߦ { launch { delay(1000L) }
 logging(request) } ผεϨουͰ
 ॲཧΛߦ͏ϥϜμ
  37. 62.

    4FUVQ $BMM 4FOE .POJUPSJOH w MBVODIؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝
 5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ MBVODIؔ਺Λ࣮ߦ { getAuth(userID)

    } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ { launch { delay(1000L) }
 logging(request) } ผεϨουͰ
 ॲཧΛߦ͏ϥϜμ
  38. 63.

    4FUVQ $BMM 4FOE .POJUPSJOH w MBVODIؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝
 5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ { launch {

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

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { launch { delay(1000L) }


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

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { launch { delay(1000L) }


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

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ { launch

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

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ { launch

    { delay(1000L) }
 logging(request) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } 5ISFBEᶅͰ
 ॲཧ͕ऴྃ w 5ISFBEᶅͷίϧʔνϯ͕ऴྃͨ͠Β5ISFBEᶄ্ͷίϧʔνϯ ͕ऴྃ͠ɺݺͼग़͠ݩͷ5ISFBEᶃͷ໭ͬͯϋϯυϦϯά͕ऴྃ
  43. 69.

    4FUVQ $BMM 4FOE .POJUPSJOH { async { delay(1000L)
 “Finish” }.await()

    } { logging(response) } { saveProfile( userID, profile ) } { getAuth(userID) } ผεϨουͰॲཧΛߦͬͯ
 ׬ྃΛ଴ͭϥϜμ 3 : asyncؔ਺ͷྫ
  44. 70.

    4FUVQ $BMM 4FOE .POJUPSJOH { async { delay(1000L)
 “Finish” }.await()

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

    4FUVQ $BMM 4FOE .POJUPSJOH w 5ISFBEᶄ্Ͱίϧʔνϯ͕4FUVQϑΣΠζͷॲཧΛ࣮ߦ ॲཧΛ࣮ߦ { async {

    delay(1000L)
 “Finish” }.await() } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) }
  46. 72.

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧ͕ऴྃ ॲཧΛ࣮ߦ { logging(response) } {

    saveProfile( userID, profile ) } { getAuth(userID) } w 4FUVQϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ
 ίϧʔνϯ͕.POJUPSJOHϑΣΠζͷॲཧΛ࣮ߦ { async { delay(1000L)
 “Finish” }.await() } ผεϨουͰॲཧΛߦͬͯ
 ׬ྃΛ଴ͭϥϜμ
  47. 73.

    4FUVQ $BMM 4FOE .POJUPSJOH w BTZODؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝
 5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ BTZODؔ਺Λ࣮ߦ { getAuth(userID)

    } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ { async { delay(1000L)
 “Finish” }.await() } ผεϨουͰॲཧΛߦͬͯ
 ׬ྃΛ଴ͭϥϜμ
  48. 74.

    4FUVQ $BMM 4FOE .POJUPSJOH w BTZODؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝
 5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ { async {

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

    4FUVQ $BMM 4FOE .POJUPSJOH { async { delay(1000L)
 “Finish” }.await()

    } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ 5ISFBEᶅ͕
 ऴΘΔ·Ͱ଴ػ 5ISFBEᶅͰ࣮ߦத ผεϨουͰॲཧΛߦͬͯ
 ׬ྃΛ଴ͭϥϜμ w 5ISFBEᶅ্ͷίϧʔνϯͷ׬ྃΛ଴ػ͍ͯ͠ΔͷͰ
 5ISFBEᶄͷ.POJUPSJOHϑΣΠζͷॲཧ΋׬ྃ͠ͳ͍··
  50. 76.

    4FUVQ $BMM 4FOE .POJUPSJOH { async { delay(1000L)
 “Finish” }.await()

    } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ ࢒ΓͷॲཧΛ࣮ߦ ผεϨουͰॲཧΛߦͬͯ
 ׬ྃΛ଴ͭϥϜμ w 5ISFBEᶅ্ͷίϧʔνϯͷ׬ྃͷ݁ՌΛड͚ͯ
 5ISFBEᶄͷ.POJUPSJOHϑΣΠζͷॲཧΛ࠶։ 5ISFBEᶅͰॲཧ͕ऴྃ
  51. 77.

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { async { delay(1000L)
 “Finish”

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

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { asyncFun(context) } { getAuth(userID)

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

    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ؔ਺ͷྫ
  54. 81.

    4FUVQ $BMM 4FOE .POJUPSJOH { val id = async {

    delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } QSPDFFE Λ࣮ߦ͢ΔϥϜμ
  55. 82.

    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Λ࣮ߦ
  56. 83.

    4FUVQ $BMM 4FOE .POJUPSJOH w 5ISFBEᶄ্Ͱίϧʔνϯ͕4FUVQϑΣΠζͷॲཧΛ࣮ߦ ॲཧΛ࣮ߦ { val id

    = async { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) }
  57. 84.

    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 Λ࣮ߦ͢ΔϥϜμ
  58. 85.

    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()) }
  59. 86.

    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 Λ࣮ߦ͢ΔϥϜμ
  60. 87.

    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ᶅͰ࣮ߦத
  61. 88.

    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ᶅͰ࣮ߦத
  62. 89.

    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ᶅͰ࣮ߦத
  63. 90.

    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ᶅͰॲཧ͕ऴྃ
  64. 91.

    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ᶅͰॲཧ͕ऴྃ
  65. 92.

    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ᶅͰॲཧ͕ऴྃ
  66. 93.

    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ᶅͰॲཧ͕ऴྃ
  67. 97.

    Continuation (ܧଓ) w TVTQFOEؔ਺Ͱதஅ͞Εͨίϧʔνϯͷঢ়ଶ w தஅ͞Εͨ෦෼Ҏ߱ͷ࢒Γͷॲཧ ίʔϧόοΫ Λද͢ w SFTVNF8JUIϝιου͸׬ྃίʔϧόοΫͰ͋Γ


    ίϧʔνϯͷ׬ྃ࣌ʹ੒ޭɾࣦഊͷ͍ͣΕ͔Λฦ͢ public interface Continuation<in T> { public val context: CoroutineContext public fun resumeWith(result: Result<T>) }
  68. 98.

    suspendؔ਺ suspend fun susFuncA() { delay(1000L) } val block: suspend

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

    suspendؔ਺ suspend fun susFuncA() { delay(1000L) } val block: suspend

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

    suspendؔ਺ suspend fun susFunc( time: Long ) : String TVTQFOEؔ਺

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

    suspend fun susFunc( time: Long ) : String { delay(time)

    return "Kotlin Fest!" } TVTQFOEؔ਺
  72. 102.

    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ؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ
  73. 103.

    (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ؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ
  74. 104.

    (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 ܕʹͳ͍ͬͯΔ
  75. 105.

    (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Λ౉͍ͯ͠Δ
  76. 106.

    (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ΛҾ਺ͱͯ͠౉͢͜ͱ͕Ͱ͖ͳ͍
  77. 107.

    (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ؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ
  78. 108.

    (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ؔ਺Λ
 ී௨ͷؔ਺͔Βݺͼग़͢ʁ
 ίϧʔνϯΛ։࢝͢Δʁ
  79. 110.

    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͸ࣗલͰ༻ҙ͢Δ͔
 طʹ։͍࢝ͯ͠Δίϧʔνϯ͔Βऔಘ͢Δ
  80. 111.

    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͸ࣗલͰ༻ҙ͢Δ͔
 طʹ։͍࢝ͯ͠Δίϧʔνϯ͔Βऔಘ͢Δ
  81. 112.

    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&/%&%ϚʔΧʔΛฦ͢
  82. 113.

    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&/%&%ϚʔΧʔΛฦ͢
  83. 114.

    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&/%&%ϚʔΧʔΛฦ͢
  84. 115.

    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͸Ͳ͏΍ͬͯऔಘͰ͖Δʁ
  85. 117.

    w ίϧʔνϯΛதஅঢ়ଶͱͯ͠ҡ࣋͢Δ৔߹
 $03065*/&@4641&/%&%ϚʔΧʔΛฦ͢ w ίϧʔνϯΛ׬ྃ͢Δ৔߹
 ݁ՌΛSFTVNF8JUIϝιουʹ౉࣮ͯ͠ߦ suspend inline fun <T>

    suspendCoroutineUninterceptedOrReturn( crossinline block: (Continuation<T>) -> Any? ): T suspendCoroutineUninterceptedOrReturn
  86. 121.

    4FUVQ $BMM 4FOE .POJUPSJOH { delay(1000L) } { getAuth(userID) }

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

    4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

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

    4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

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

    4FUVQ $BMM 4FOE .POJUPSJOH { delay(1000L) } { getAuth(userID) }

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

    4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

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

    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ΛऔΓग़ͯ͠
 Ҿ਺ͷϥϜμࣜͷதͰѻ͏͜ͱ͕Ͱ͖Δ
  92. 127.

    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
  93. 128.

    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?
  94. 129.

    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Λ
 ࡞੒ͤͣʹίϧʔνϯΛ։࢝Ͱ͖Δ
  95. 130.

    suspendCoroutineUninterceptedOrReturn { continuation -> do { val rc = PhaseʹׂΓ౰ͯΒΕͨϥϜμࣜ.

    startCoroutineUninterceptedOrReturn(ɾɾɾ) ɾɾɾ } while (true) COROUTINE_SUSPENDED } w TVTQFOE$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOͱ
 TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOΛ૊Έ߹ΘͤΔ͜ͱͰ
 $POUJOVBUJPOΛڞ༗͠ͳ͕ΒίϧʔνϯΛ࡞੒͍ͯ͠Δ
  96. 131.

    4FUVQ $BMM 4FOE .POJUPSJOH { delay(1000L) } { getAuth(userID) }

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

    4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

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

    proceedؔ਺ͷ࣮૷ 4FUVQ $BMM 4FOE .POJUPSJOH { val id = async

    { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } QSPDFFE Λ࣮ߦ͢ΔϥϜμ
  99. 134.

    4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࣮ߦ { val id = async

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

    suspendCoroutineUninterceptedOrReturn { continuation -> do { ɾɾɾ val rc =

    PhaseʹׂΓ౰ͯΒΕͨϥϜμࣜ. startCoroutineUninterceptedOrReturn(ɾɾɾ) ɾɾɾ } while (true) COROUTINE_SUSPENDED } w QSPDFFEϝιουΛ࣮ߦ͢Δͱ$POUJOVBUJPOΛ৽ͨʹ࡞੒ͯ͠
 ผεϨουͰಈ࡞͢ΔίϧʔνϯΛ։࢝͢Δ
  101. 136.

    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") } } }
  102. 137.

    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") } } }
  103. 138.

    ಠࣗͷCoroutineStart 4FUVQ $BMM 4FOE .POJUPSJOH { delay(1000L) } { delay(1000L)

    } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) }
  104. 139.

    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
  105. 140.

    4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

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

    4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

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

    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Λڞ༗Ͱ͖Δ
  108. 143.

    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΋Ҿ͖౉͢͜ͱ͸
 ௨ৗ͸ෆՄೳ
  109. 144.

    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 ૊ΈࠐΈؔ਺ͱ͍ۙॲཧΛҎԼͷؔ਺Ͱ࣮ݱ͍ͯ͠Δ
  110. 145.

    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*
  111. 146.

    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* ϥΠϒϥϦ͔Βఏڙ͞Ε͍ͯΔؔ਺
  112. 147.

    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ܕʹ
 Ωϟετ͞Ε͔ͯΒ࣮ߦ͞Ε͍ͯΔ
  113. 148.

    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 ͕࣮ͨͬͯ͠ߦ࣌ͷΩϟετ͸੒ޭ͢Δ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ
  114. 149.

    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 ͕࣮ͨͬͯ͠ߦ࣌ͷΩϟετ͸੒ޭ͢Δ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ ίϯύΠϧޙͷίʔυͷγάωνϟΛ
 ༧ଌͯ͠ڧ੍Ωϟετ͍ͤͯ͞Δ
  115. 150.

    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*Λ
 ࣗ෼Ͱ࣮૷͢Δ͜ͱ͕Ͱ͖Δ
  116. 151.
  117. 153.

    4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

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