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. Coroutines͔Βඥղ͘ Ktorͷ࢓૊Έ Kotlin Fest 2019 
 08/24 (Sat.) 
 Recruit

    Lifestyle. Yuji Koyano
  2. ิ଍ w ͜ͷεϥΠυதͷ,UPSͷઆ໌͸
 جຊతʹ4FSWFSTJEF,UPSͷΈΛର৅ͱ͍ͯ͠·͢ɻ
 ͱ͸͍͑ɺ$MJFOU4JEF,UPSʹ΋ڞ௨͢Δ಺༰͸ଟ͍Ͱ͢  w ͜ͷεϥΠυதͷʮίϧʔνϯΛ࡞੒ɾ։࢝͢Δʯ͸
 ޙड़͢ΔTUBSU$PSPVUJOFϝιου΍ͦͷྨࣅͷؔ਺Λ
 ࣮ߦ͢Δɺͱ͍͏ҙຯͰ࢖͍ͬͯ·͢ɻ

    w $PSPVUJOF͸+7.࣮૷Λର৅ͱ͍ͯ͠·͢
  3. ࣗݾ঺հ

  4. @bandwagondagon ykoyano Yuji Koyano @bandwagondagon ykoyano w 3FDSVJU-JGFTUZMFʹͯ
 "OESPJEΤϯδχΞͱͯ͠
 "JSϝΠτͱ͍͏ΞϓϦΛ։ൃத

    w ࠷ۙ͸ɹɹ&OWPZ.PCJMFͰ༡ΜͰ͍·͢
  5. Έͳ͞Μɺ,PUMJO͸ѪͰ͍ͯ·͔͢ʁ

  6. ༷ʑͳѪͰํ w "OESPJE w J04 ,PUMJO/BUJWF  w +BWB4DSJQU w

    4FWFS4JEF,PUMJO
  7. w "OESPJE w J04 ,PUMJO/BUJWF  w +BWB4DSJQU w 4FWFS4JEF,PUMJO

    ༷ʑͳѪͰํ
  8. None
  9. Ktorͱ͸ʁ w +FU#SBJOTࣾ੡ͷ044 w 4FSWFSαΠυͱ$MJFOUαΠυͷͭͷϓϩδΣΫτ͕͋Δ
 4FSWFSܰྔͳ8FC"QQMJDBUJPO'SBNFXPSLΛఏڙ
 $MJFOU"TZODISPOPVT)UUQ$MJFOUΛఏڙ w ,PUMJOݴޠͷػೳΛϑϧʹ׆༻͍ͯ͠Δͷ͕ಛ௃
 FY$PSPVUJOFT

    ,PUMJO/BUJWF .VMUJQMBUGPSN
  10. Ktorͱ͸ʁ w +FU#SBJOTࣾ੡ͷ044 w 4FSWFSαΠυͱ$MJFOUαΠυͷͭͷϓϩδΣΫτ͕͋Δ
 4FSWFSܰྔͳ8FC"QQMJDBUJPO'SBNFXPSLΛఏڙ
 $MJFOU"TZODISPOPVT)UUQ$MJFOUΛఏڙ w ,PUMJOݴޠͷػೳΛϑϧʹ׆༻͍ͯ͠Δͷ͕ಛ௃
 FY$PSPVUJOFT

    ,PUMJO/BUJWF .VMUJQMBUGPSN
  11. ͜ͷηογϣϯͷ໨త w ,UPSͷઃܭ΍ಛ௃ɺࢥ૝ͳͲΛཧղ͢Δ͜ͱͰ
 4FSWFS4*EF,PUMJOͱͯ͠ͷ,UPSͷਂ͍ཧղΛಘΔ w ,UPS͕$PSPVUJOFTΛ࢖ͬͯͲͷΑ͏ʹඇಉظ
 ϓϩάϥϛϯάϞσϧΛ࣮ݱ͍ͯ͠Δͷ͔Λཧղ͢Δ͜ͱͰ
 $PSPVUJOFTͷԠ༻తͳ࢖͍ํΛ஌ͬͯ΋Β͏

  12. ͜ͷηογϣϯͷ໨త w ,UPSͷઃܭ΍"1* w $PSPVUJOFͷ
 ௿Ϩϕϧͳ"1*ͷ঺հ w 4FSWFS4JEF,UPS w ࣮ફతͳ,UPSͷ5JQT΍ӡ༻ࣄྫ

    w $PSPVUJOFͷ
 Ұൠతͳ஌ࣝ΍࢖͍ํ w $MJFOU4JEF,UPS ࿩͢͜ͱ ࿩͞ͳ͍͜ͱ
  13. $PSPVUJOFTͷ௿Ϩϕϧ"1* ,UPSͱඇಉظॲཧύΠϓϥΠϯ ,UPSΛ$PSPVUJOFTͰඥղ͘ ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝

  14. $PSPVUJOFTͷ௿Ϩϕϧ"1* ,UPSͱඇಉظॲཧύΠϓϥΠϯ ,UPSΛ$PSPVUJOFTͰඥղ͘ ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝

  15. w ,UPSͷઃܭࢥ૝ͷҰͭɻ௚༁͢ΔͱʮࣗઆΛ࣋ͨͳ͍ʯ w ϑϨʔϜϫʔΫଆ͸ΞϓϦߏ੒΍ػೳΛۃྗڧ੍͠ͳ͍ͨΊ
 ΞϓϦέʔγϣϯ։ൃऀͷҙࢥʹଟ͕͘ҕͶΒΕ͍ͯΔ
 DG/PEFKTͷϑϨʔϜϫʔΫ&YQSFTT Unopinionated

  16. w ϑϨʔϜϫʔΫͷҰൠతͳओཁػೳΛίΞίϯϙʔωϯτ͔Β
 ෼཭͢Δ͜ͱͰϚΠΫϩϑϨʔϜϫʔΫΛ࣮ݱ
 DG3VCZPO3BJMTͱ4JOBUSB 4QSJOH'SBNFXPSL w σϑΥϧτઃఆͰ͸ϩΪϯάػೳ΍
 ςϯϓϨʔτΤϯδϯ΍+TPO.BQQFSͳͲ΋ಋೖ͞Ε͍ͯͳ͍ ബ͍ϑϨʔϜϫʔΫ

  17. ϚΠΫϩϑϨʔϜϫʔΫͷϝϦοτ w ඞཁ࠷খݶͷߏ੒Ͱ։ൃΛ։࢝Ͱ͖ΔͷͰ
 ϓϩτλΠϐϯάͱͯ͠ͷΞϓϦέʔγϣϯ΍
 ϚΠΫϩαʔϏεతʹ୯Ұͷ੹຿Λ࣋ͭΞϓϦέʔγϣϯΛ
 খ͘͞࡞Γ࢝ΊΔͷʹద͍ͯ͠Δ w ҉໧తͳઃఆ΍ػೳ͕΄ͱΜͲͳ͍ͨΊ
 ϑϨʔϜϫʔΫͱ࣮ͯ͠ߦ͞Ε͍ͯΔػೳΛ
 ΞϓϦέʔγϣϯ։ൃऀ͕೺Ѳ͢Δͷ͕ൺֱత༰қ

  18. $PSPVUJOFTͷ௿Ϩϕϧ"1* ,UPSͱඇಉظॲཧύΠϓϥΠϯ ,UPSΛ$PSPVUJOFTͰඥղ͘ ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝

  19. FeatureʹΑΔϓϥάΠϯػߏ w ೝূ΍%*ͳͲͷ࣮ફతͳػೳ͔ΒϧʔςΟϯά΍
 ϩΪϯάͳͲͷجຊతͳػೳ·Ͱͷ΄ͱΜͲ͕
 'FBUVSFͱ͍͏ϓϥάΠϯܗࣜͰຊମ͔Β
 ੾Γग़ͯ͠ఏڙ͞Ε͍ͯΔ w 'FBUVSFΛΞϓϦέʔγϣϯʹJOTUBMM͢Δ͜ͱͰ
 ࣗ༝ʹػೳΛ௥ՃͰ͖Δ w

    ಠࣗʹ$VTUPN'FBUVSFΛ࣮૷͢Δ͜ͱ΋Մೳ
  20. fun Application.main() { routing { get("/kotline_fest") { call.respondText { "Kotlin

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

    { "Kotlin Fest 2019!” } } } } Featureͷinstallྫ w JOTUBMMϝιουΛ࢖༻ͯ͠ΞϓϦέʔγϣϯʹػೳ௥Ճ
  22. ύΠϓϥΠϯػߏ w ,UPS͕ϦΫΤετΛड͚ͯॲཧΛߦ্͍ͬͯ͘Ͱ
 ΞϓϦέʔγϣϯ։ൃऀ͕ॊೈʹ'FBUVSF΍3PVUJOHຖͷॱংΛ
 ఆٛͰ͖ΔΑ͏ͳܭࢉύΠϓϥΠϯΛఏڙ w ܭࢉύΠϓϥΠϯΛ֦ு͢ΔͨΊͷ"1*΋ఏڙ͞Ε͍ͯͯ
 ಠࣗͷܭࢉύΠϓϥΠϯΛ࣮૷ͯ͠
 $VTUPN'FBUVSFͱͯ͠JOTUBMM ࣮ߦ͢Δ͜ͱ΋Մೳ

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

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

    saveProfile( userID, profile ) } w ,UPS͸ϦΫΤετΛड͚ΔͱίϧʔνϯΛ։࢝ͯ͠
 ܭࢉύΠϓϥΠϯʹׂΓ౰ͯΒΕͨॲཧΛ࣮ߦ͍ͯ͘͠ 1IBTF 1IBTF 1IBTF 1IBTF
  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) { ɹɹɹɹɹɹɹɾɾɾ } }
  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) { ɹɹɹɹɹɹɹɾɾɾ } }
  27. { setHeader() } { getAuth(userID) } { logging(response) } {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    { logging(response) } { saveProfile( userID, profile ) }
  43. ϓϥάΠϯͱύΠϓϥΠϯػߏ w ,UPSຊମ͸࠷௿ݶͷػೳ͔࣋ͨ͠ͳ͍୅ΘΓʹ
 'FBUVSFΛ࢖ͬͨϓϥάΠϯػߏʹΑͬͯ
 Ϣʔβʔ͕ࣗ༝ʹػೳΛ௥Ճ͢Δ͜ͱ͕Ͱ͖Δ w ,UPS͔Βఏڙ͞ΕΔܭࢉύΠϓϥΠϯػߏͱ"1*ʹΑͬͯ
 ΞϓϦέʔγϣϯ։ൃऀ͕ݻ༗ͷϧʔςΟϯάॲཧ΍
 ෳ਺ϧʔςΟϯάʹ·͕ͨͬͨڞ௨ॲཧΛॊೈͳॱ൪Ͱ
 ࣮ߦͤ͞Δ͜ͱ͕Մೳ

  44. $PSPVUJOFTͷ௿Ϩϕϧ"1* ,UPSͱඇಉظॲཧύΠϓϥΠϯ ,UPSΛ$PSPVUJOFTͰඥղ͘ ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝

  45. w ίϧʔνϯΛར༻ͯ͠ඇಉظϓϩάϥϛϯάϞσϧΛ
 ѻ͍΍͍͢ܗͰΞϓϦέʔγϣϯ։ൃऀʹఏڙ w ύΠϓϥΠϯ಺Ͱࣗ༝ʹඇಉظॲཧΛ։࢝͢Δ͜ͱ͕Ͱ͖Δ ඇಉظॲཧύΠϓϥΠϯ

  46. w TVTQFOEؔ਺ʹΑͬͯҰ࣌தஅ͢Δྫ w MBVODIؔ਺ͰίϧʔνϯΛผεϨουͰ։࢝͢Δྫ w BTZODؔ਺ͰίϧʔνϯΛผεϨουͰ։࢝͢Δྫ w QSPDFFEϝιουͱBXBJUؔ਺Λ૊Έ߹ΘͤΔྫ ঺հ͢ΔඇಉظॲཧύΠϓϥΠϯͷ࢖͍ํ

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

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

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

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

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

    logging(response) } { saveProfile( userID, profile ) } { getAuth(userID) } w 4FUVQϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ
 ίϧʔνϯ͕.POJUPSJOHϑΣΠζͷॲཧΛ࣮ߦ Ұ࣌தஅ͢Δؔ਺
  52. 4FUVQ $BMM 4FOE .POJUPSJOH w ॲཧΛҰ࣌தஅͯ͠ɺॲཧΛ࠶։͢Δ·Ͱίϧʔνϯ্Ͱ଴ػ
 5ISFBEᶄ͸ผͷϦΫΤετͷॲཧΛड͚෇͚ΒΕΔΑ͏ʹͳΔ ॲཧΛҰ࣌தஅ { delay(1000L)

    } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ Ұ࣌தஅ͢Δؔ਺
  53. 4FUVQ $BMM 4FOE .POJUPSJOH ॲཧΛ࠶։ { delay(1000L) } { getAuth(userID)

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

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

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

    } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } w 4FOEϑΣΠζͷॲཧ͕׬ྃͨ͠Β5ISFBEᶄ্ͷίϧʔνϯ͕ ऴྃ͠ɺݺͼग़͠ݩͷ5ISFBEᶃͷ໭ͬͯϋϯυϦϯά͕ऴྃ
  57. w ॲཧ͕Ұ࣌தஅ͍ͯ͠ΔؒʹύΠϓϥΠϯ࣮ߦεϨουΛ
 ผͷϦΫΤετͷͨΊʹར༻͢Δ͜ͱ͕Ͱ͖Δ w ແҋʹεϨουΛੜ੒ͤͣɺޮ཰తʹαʔόʔͷϦιʔεΛ
 ׆༻͢Δ͜ͱ͕Ͱ͖Δ 1 : suspendؔ਺ʹΑͬͯҰ࣌தஅ͢Δྫ

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

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

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

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

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

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

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


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


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

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

    { delay(1000L) }
 logging(request) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } 5ISFBEᶅͰ
 ॲཧ͕ऴྃ w 5ISFBEᶅͷίϧʔνϯ͕ऴྃͨ͠Β5ISFBEᶄ্ͷίϧʔνϯ ͕ऴྃ͠ɺݺͼग़͠ݩͷ5ISFBEᶃͷ໭ͬͯϋϯυϦϯά͕ऴྃ
  68. 2 : launchؔ਺ͷྫ w MBVODIίϧʔνϯϏϧμʔΛύΠϓϥΠϯ্Ͱ࣮ߦ͢Δͱ
 ผεϨουͰ৽ͨʹίϧʔνϯΛ։࢝ͯ͠
 ݩͷύΠϓϥΠϯͷॲཧͱ͸ฏߦʹܭࢉΛߦ͏͜ͱ͕Ͱ͖Δ w ͜ΕʹΑͬͯ*0଴͕ͪ௕͍ॲཧΛMBVODIίϧʔνϯϏϧμʔͰͷ
 ίϧʔνϯͰ࣮ߦ͢Δ͜ͱʹΑͬͯ


    ޮ཰తʹฏߦॲཧΛߦ͏͜ͱ͕Ͱ͖Δ৔߹͕͋Δ
  69. 4FUVQ $BMM 4FOE .POJUPSJOH { async { delay(1000L)
 “Finish” }.await()

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

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

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

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

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

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

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

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

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

    } { logging(response) } { saveProfile( userID, profile ) } ॲཧ͕ऴྃ ॲཧ͕ऴྃ w 5ISFBEᶄͷ.POJUPSJOHϑΣΠζͷॲཧ͕ऴྃͯ͠
 ΍ͬͱ$BMMϑΣΠζͷ࣮ߦΛ։࢝Ͱ͖Δ ͜ͷผεϨουͷॲཧ଴ͪͷ࣌ؒΛ
 ༗ޮʹ࢖͏ͨΊͷ"1*͕
 ,UPS͔Βఏڙ͞Ε͍ͯ·͢ʂ
  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ؔ਺ͷྫ
  80. Proceedϝιου w ݱࡏ࣮ߦதͷϥϜμࣜΛҰ࣌தஅ͠৽͍͠ίϧʔνϯΛ
 ։࢝ͯ͠ޙஈͷύΠϓϥΠϯΛ࣮ߦ͢Δ"1*
 w ޙஈͷύΠϓϥΠϯͷॲཧ͕׬ྃ͢ΔͱQSPDFFE Λ࣮ߦ
 ͨ͠ϥϜμࣜͷॲཧ͕࠶։͞ΕΔ

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

    delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } QSPDFFE Λ࣮ߦ͢ΔϥϜμ
  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Λ࣮ߦ
  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 ) }
  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 Λ࣮ߦ͢ΔϥϜμ
  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()) }
  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 Λ࣮ߦ͢ΔϥϜμ
  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ᶅͰ࣮ߦத
  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ᶅͰ࣮ߦத
  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ᶅͰ࣮ߦத
  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ᶅͰॲཧ͕ऴྃ
  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ᶅͰॲཧ͕ऴྃ
  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ᶅͰॲཧ͕ऴྃ
  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ᶅͰॲཧ͕ऴྃ
  94. 4 : proceedϝιουͱasyncؔ਺ͷྫ w ,UPS͔Βఏڙ͞Ε͍ͯΔQSPDFFEϝιουΛ࢖͏͜ͱͰ
 ผεϨουͷίϧʔνϯ͔ΒͷฦΓ஋Λ଴͍ͬͯΔؒʹ
 ޙଓͷผͷύΠϓϥΠϯͷॲཧΛ࣮ߦ͢Δ͜ͱ͕Ͱ͖Δ w ֤ύΠϓϥΠϯϑΣΠζͰͷϥϜμࣜΛ
 ผͷ'FBUVSFͰಠཱʹఆٛ͠ͳ͕Β΋


    ύΠϓϥΠϯϑΣΠζΛލ͍ͰඇಉظॲཧΛ࣮ߦ͢Δ͜ͱͰ
 ΑΓޮ཰తʹܭࢉΛߦ͏͜ͱ͕Ͱ͖Δ
  95. $PSPVUJOFTͷ௿Ϩϕϧ"1* ,UPSͱඇಉظॲཧύΠϓϥΠϯ ,UPSΛ$PSPVUJOFTͰඥղ͘ ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝

  96. Coroutinesͷ௿Ϩϕϧͳૢ࡞ w $PSPVUJOFΛγϯϓϧʹ࢖͏͚ͩͳΒҙࣝͤͣͱ΋ࠔΒͳ͍
 ͜ͱ͕ଟ͍͕ϥΠϒϥϦΛ࡞Δͱ͖ͳͲ͸ѻ͑Δͱ໾ཱͭ w $POUJOVBUJPOTVTQFOEؔ਺ͷࣗಈมܗ w TUBSU$PSPVUJOF
 TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSO w

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


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

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

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

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

    return "Kotlin Fest!" } TVTQFOEؔ਺
  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ؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ
  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ؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ
  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 ܕʹͳ͍ͬͯΔ
  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Λ౉͍ͯ͠Δ
  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ΛҾ਺ͱͯ͠౉͢͜ͱ͕Ͱ͖ͳ͍
  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ؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ
  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ؔ਺Λ
 ී௨ͷؔ਺͔Βݺͼग़͢ʁ
 ίϧʔνϯΛ։࢝͢Δʁ
  109. startCoroutine w ίϧʔνϯΛ࡞੒ͯ͠ݱࡏͷεϨουͰ
 ϨγʔόʔͰ͋ΔTVTQFOEϥϜμΛ࣮ߦ͢Δ w MBVODI BTZODͳͲͷίϧʔνϯϏϧμʔ΋
 ಺෦తʹݺͼग़ͯ͠ίϧʔνϯΛ࡞੒͍ͯ͠Δ public fun

    <T> (suspend () -> T).startCoroutine( completion: kotlin.coroutines.Continuation<T> ): kotlin.Unit { /* compiled code */ }
  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͸ࣗલͰ༻ҙ͢Δ͔
 طʹ։͍࢝ͯ͠Δίϧʔνϯ͔Βऔಘ͢Δ
  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͸ࣗલͰ༻ҙ͢Δ͔
 طʹ։͍࢝ͯ͠Δίϧʔνϯ͔Βऔಘ͢Δ
  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&/%&%ϚʔΧʔΛฦ͢
  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&/%&%ϚʔΧʔΛฦ͢
  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&/%&%ϚʔΧʔΛฦ͢
  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͸Ͳ͏΍ͬͯऔಘͰ͖Δʁ
  116. suspendCoroutineUninterceptedOrReturn w ίϧʔνϯ಺ͰݺͿ͜ͱͰίϧʔνϯ͕தஅͨ͠࢒Γͷঢ়ଶΛ
 $POUJOVBUJPOΠϯελϯεͱͯ͠औಘͰ͖Δ"1* w ϥϜμࣜͰ$POUJOVBUJPOΠϯελϯεΛࢀর͠
 ίϧʔνϯͷதஅɾ׬ྃͱ͍ͬͨঢ়ଶΛ௚઀੍ޚͰ͖Δ suspend inline fun

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

    suspendCoroutineUninterceptedOrReturn( crossinline block: (Continuation<T>) -> Any? ): T suspendCoroutineUninterceptedOrReturn
  118. $PSPVUJOFTͷ௿Ϩϕϧ"1* ,UPSͱඇಉظॲཧύΠϓϥΠϯ ,UPSΛ$PSPVUJOFTͰඥղ͘ ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝

  119. KtorΛCoroutinesͰඥղ͘ w ύϑΥʔϚϯεΛߟྀͨ͠$PSPVUJOFͷੜ੒ w QSPDFFEؔ਺ͷॲཧΛͲ͏΍࣮ͬͯݱ͍ͯ͠Δͷ͔ w $PSPVUJOFΛ։࢝͢Δͱ͖ʹ$POUJOVBUJPO͚ͩͰͳ͘
 ೚ҙͷΦϒδΣΫτ΋Ҿ͖౉͢ํ๏

  120. ύϑΥʔϚϯεΛߟྀͨ͠Coroutineͷੜ੒ 4FUVQ $BMM 4FOE .POJUPSJOH { delay(1000L) } { getAuth(userID)

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

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

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

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

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

    { logging(response) } { saveProfile( userID, profile ) } w ࠷ॳͷίϧʔνϯ͸֤1IBTFίϧʔνϯΛ࡞੒͢Δࡍʹ
 ৽ͨʹ$POUJOVBUJPOΛ࡞Βͣɺࣗ਎ͷ$POUJOVBUJPOΛ
 Ҿ͖౉͍ͯ͠Δ ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%
  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ΛऔΓग़ͯ͠
 Ҿ਺ͷϥϜμࣜͷதͰѻ͏͜ͱ͕Ͱ͖Δ
  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
  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?
  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Λ
 ࡞੒ͤͣʹίϧʔνϯΛ։࢝Ͱ͖Δ
  130. suspendCoroutineUninterceptedOrReturn { continuation -> do { val rc = PhaseʹׂΓ౰ͯΒΕͨϥϜμࣜ.

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

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

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

    { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) } QSPDFFE Λ࣮ߦ͢ΔϥϜμ
  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ᶅͰ࣮ߦத
  135. suspendCoroutineUninterceptedOrReturn { continuation -> do { ɾɾɾ val rc =

    PhaseʹׂΓ౰ͯΒΕͨϥϜμࣜ. startCoroutineUninterceptedOrReturn(ɾɾɾ) ɾɾɾ } while (true) COROUTINE_SUSPENDED } w QSPDFFEϝιουΛ࣮ߦ͢Δͱ$POUJOVBUJPOΛ৽ͨʹ࡞੒ͯ͠
 ผεϨουͰಈ࡞͢ΔίϧʔνϯΛ։࢝͢Δ
  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") } } }
  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") } } }
  138. ಠࣗͷCoroutineStart 4FUVQ $BMM 4FOE .POJUPSJOH { delay(1000L) } { delay(1000L)

    } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) }
  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
  140. 4FUVQ $BMM 4FOE .POJUPSJOH { asyncFun(context) } { getAuth(userID) }

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

    { logging(response) } { saveProfile( userID, profile ) } w "QQMJDBUJPO$BMM͸ύΠϓϥΠϯ಺ʹάϩʔόϧͳม਺ͱͯ͠
 ڞ༗͞ΕΔͷͰ͸ͳ͘ɺ1JQFMJOF1IBTFຖͷίϧʔνϯੜ੒࣌ʹ
 $POUJOVBUJPOͱҰॹʹҾ͖౉͍ͯ͠Δ "QQMJDBUJPO$BMM ίϧʔνϯΛ։࢝͢Δͱ͖ʹ
 $POUJOVBUJPOҎ֎ͷΦϒδΣΫτΛ
 Ͳ͏΍ͬͯ౉͢ͷ͔ʁ
  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Λڞ༗Ͱ͖Δ
  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΋Ҿ͖౉͢͜ͱ͸
 ௨ৗ͸ෆՄೳ
  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 ૊ΈࠐΈؔ਺ͱ͍ۙॲཧΛҎԼͷؔ਺Ͱ࣮ݱ͍ͯ͠Δ
  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*
  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* ϥΠϒϥϦ͔Βఏڙ͞Ε͍ͯΔؔ਺
  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ܕʹ
 Ωϟετ͞Ε͔ͯΒ࣮ߦ͞Ε͍ͯΔ
  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 ͕࣮ͨͬͯ͠ߦ࣌ͷΩϟετ͸੒ޭ͢Δ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ
  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 ͕࣮ͨͬͯ͠ߦ࣌ͷΩϟετ͸੒ޭ͢Δ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ ίϯύΠϧޙͷίʔυͷγάωνϟΛ
 ༧ଌͯ͠ڧ੍Ωϟετ͍ͤͯ͞Δ
  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*Λ
 ࣗ෼Ͱ࣮૷͢Δ͜ͱ͕Ͱ͖Δ
  151. ·ͱΊ

  152. $PSPVUJOFTͷ௿Ϩϕϧ"1*ؔ਺ ,UPSͱඇಉظॲཧύΠϓϥΠϯ ,UPSΛ$PSPVUJOFTͰඥղ͘ ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝

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

    { logging(response) } { saveProfile( userID, profile ) }
  154. ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝ w ,UPS͕࠾༻͍ͯ͠ΔϚΠΫϩϑϨʔϜϫʔΫͳઃܭࢥ૝Λ঺հ w ,UPSຊମࣗମ͸8FC"QQ'SBNFXPSLͱͯ͠ඞཁ࠷௿ݶͷ
 ػೳ͔࣮͠૷͍ͯ͠ͳ͍ͨΊɺΞϓϦέʔγϣϯ։ൃऀ͕
 খ͘͞ߴ଎ʹΞϓϦέʔγϣϯΛ։ൃ͍ͯ͘͠ద͍ͯ͠Δ

  155. ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ w ,UPSͷϝΠϯͷઃܭͰ͋Δ
 'FBUVSFʹΑΔϓϥάΠϯػߏͱύΠϓϥΠϯػߏΛ঺հ w ΞϓϦέʔγϣϯ։ൃऀʹඞཁͳػೳʹԠͯ͡ॊೈʹ
 ύΠϓϥΠϯΛߏ੒ΛͰ͖ΔΑ͏ͳ"1*Λఏڙ͍ͯ͠Δ

  156. KtorͱඇಉظॲཧύΠϓϥΠϯ w ,UPSͷඇಉظॲཧύΠϓϥΠϯ্ͰதஅॲཧΛ։࢝ͨ͠Γ
 ผεϨουͰಈ࡞͢ΔΑ͏ͳίϧʔνϯΛ։࢝ͨ͠ͱ͖ʹ
 ύΠϓϥΠϯͷ֤ϑΣΠζ͕ͲͷΑ͏ʹ࣮ߦ͞ΕΔ͔Λ঺հ w QSPFFEϝιουͳͲɺΑΓޮ཰తʹॲཧΛ࣮ߦ͞ΕΔͨΊͷ
 "1*͕,UPS͔Βఏڙ͞Ε͍ͯΔ

  157. Coroutinesͷ௿ϨϕϧAPI w ίϧʔνϯͰߴ͍ύϑΥʔϚϯεͳͲΛٻΊΔࡍʹ͸
 ॏཁʹͳͬͯ͘ΔΑ͏ͳ௿Ϩϕϧͷ"1*Λ঺հ w $POUJOVBUJPOTVTQFOEؔ਺ͷࣗಈมܗ w TUBSU$PSPVUJOF
 TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSO w

    TVTQFOE$PSPVUJOF6OJOUFSDFQUFE0S3FUVSO
  158. KtorΛCoroutinesͰඥղ͘ w ඇಉظॲཧύΠϓϥΠϯͰͷύϑΥʔϚϯεΛ
 ͋͛ΔͨΊʹ಺෦తʹίϧʔνϯͷ௿Ϩϕϧ"1*Λ׆༻ͨ͠
 ༷ʑͳςΫχοΫΛ঺հ w ,UPSΛ࢖Θͳ͍ΞϓϦέʔγϣϯ΍࡞ΔࡍͰ΋
 େྔͷίϧʔνϯΛ࢖ͬͯߴ͍ύϑΥʔϚϯεΛ
 ٻΊΒΕΔΑ͏ͳঢ়گͰ͸ࢀߟʹͳΔΑ͏ͳ࣮૷͕ଘࡏ