Slide 1

Slide 1 text

Coroutines͔Βඥղ͘ Ktorͷ࢓૊Έ Kotlin Fest 2019 
 08/24 (Sat.) 
 Recruit Lifestyle. Yuji Koyano

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

ࣗݾ঺հ

Slide 4

Slide 4 text

@bandwagondagon ykoyano Yuji Koyano @bandwagondagon ykoyano w 3FDSVJU-JGFTUZMFʹͯ
 "OESPJEΤϯδχΞͱͯ͠
 "JSϝΠτͱ͍͏ΞϓϦΛ։ൃத w ࠷ۙ͸ɹɹ&OWPZ.PCJMFͰ༡ΜͰ͍·͢

Slide 5

Slide 5 text

Έͳ͞Μɺ,PUMJO͸ѪͰ͍ͯ·͔͢ʁ

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

͜ͷηογϣϯͷ໨త w ,UPSͷઃܭ΍"1* w $PSPVUJOFͷ
 ௿Ϩϕϧͳ"1*ͷ঺հ w 4FSWFS4JEF,UPS w ࣮ફతͳ,UPSͷ5JQT΍ӡ༻ࣄྫ w $PSPVUJOFͷ
 Ұൠతͳ஌ࣝ΍࢖͍ํ w $MJFOU4JEF,UPS ࿩͢͜ͱ ࿩͞ͳ͍͜ͱ

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

fun Application.main() { install(DefaultHeaders) install(CallLogging) routing { get("/kotline_fest") { call.respondText { "Kotlin Fest 2019!” } } } } Featureͷinstallྫ w JOTUBMMϝιουΛ࢖༻ͯ͠ΞϓϦέʔγϣϯʹػೳ௥Ճ

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

4FUVQ $BMM 4FOE .POJUPSJOH w 1JQFMJOF1IBTF΁ͷॲཧͷׂΓ౰ͯ͸
 'FBUVSFͷJOTUBMM΍3PVUJOHͷఆٛʹΑͬͯߦΘΕΔ %FGBVMU)FBEFS $BMM-PHHJOH 'FBUVSF 3PVUJOH

Slide 30

Slide 30 text

4FUVQ $BMM 4FOE .POJUPSJOH %FGBVMU)FBEFS $BMM-PHHJOH 'FBUVSF 3PVUJOH JOTUBMM w 1JQFMJOF1IBTF΁ͷॲཧͷׂΓ౰ͯ͸
 'FBUVSFͷJOTUBMM΍3PVUJOHͷఆٛʹΑͬͯߦΘΕΔ
 ˞ͻͱͭͷϑΣΠζʹෳ਺ͷॲཧΛׂΓ౰ͯΔ͜ͱ΋Մೳ

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

w ॲཧ͕Ұ࣌தஅ͍ͯ͠ΔؒʹύΠϓϥΠϯ࣮ߦεϨουΛ
 ผͷϦΫΤετͷͨΊʹར༻͢Δ͜ͱ͕Ͱ͖Δ w ແҋʹεϨουΛੜ੒ͤͣɺޮ཰తʹαʔόʔͷϦιʔεΛ
 ׆༻͢Δ͜ͱ͕Ͱ͖Δ 1 : suspendؔ਺ʹΑͬͯҰ࣌தஅ͢Δྫ

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

2 : launchؔ਺ͷྫ w MBVODIίϧʔνϯϏϧμʔΛύΠϓϥΠϯ্Ͱ࣮ߦ͢Δͱ
 ผεϨουͰ৽ͨʹίϧʔνϯΛ։࢝ͯ͠
 ݩͷύΠϓϥΠϯͷॲཧͱ͸ฏߦʹܭࢉΛߦ͏͜ͱ͕Ͱ͖Δ w ͜ΕʹΑͬͯ*0଴͕ͪ௕͍ॲཧΛMBVODIίϧʔνϯϏϧμʔͰͷ
 ίϧʔνϯͰ࣮ߦ͢Δ͜ͱʹΑͬͯ
 ޮ཰తʹฏߦॲཧΛߦ͏͜ͱ͕Ͱ͖Δ৔߹͕͋Δ

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

4FUVQ $BMM 4FOE .POJUPSJOH w 5ISFBEᶄ্Ͱίϧʔνϯ͕4FUVQϑΣΠζͷॲཧΛ࣮ߦ ॲཧΛ࣮ߦ { async { delay(1000L)
 “Finish” }.await() } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) }

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

Proceedϝιου w ݱࡏ࣮ߦதͷϥϜμࣜΛҰ࣌தஅ͠৽͍͠ίϧʔνϯΛ
 ։࢝ͯ͠ޙஈͷύΠϓϥΠϯΛ࣮ߦ͢Δ"1*
 w ޙஈͷύΠϓϥΠϯͷॲཧ͕׬ྃ͢ΔͱQSPDFFE Λ࣮ߦ
 ͨ͠ϥϜμࣜͷॲཧ͕࠶։͞ΕΔ

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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Λ࣮ߦ

Slide 83

Slide 83 text

4FUVQ $BMM 4FOE .POJUPSJOH w 5ISFBEᶄ্Ͱίϧʔνϯ͕4FUVQϑΣΠζͷॲཧΛ࣮ߦ ॲཧΛ࣮ߦ { val id = async { delay(1000L)
 “Finish” }
 proceed() logging(id.await()) } { getAuth(userID) } { logging(response) } { saveProfile( userID, profile ) }

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

4 : proceedϝιουͱasyncؔ਺ͷྫ w ,UPS͔Βఏڙ͞Ε͍ͯΔQSPDFFEϝιουΛ࢖͏͜ͱͰ
 ผεϨουͷίϧʔνϯ͔ΒͷฦΓ஋Λ଴͍ͬͯΔؒʹ
 ޙଓͷผͷύΠϓϥΠϯͷॲཧΛ࣮ߦ͢Δ͜ͱ͕Ͱ͖Δ w ֤ύΠϓϥΠϯϑΣΠζͰͷϥϜμࣜΛ
 ผͷ'FBUVSFͰಠཱʹఆٛ͠ͳ͕Β΋
 ύΠϓϥΠϯϑΣΠζΛލ͍ͰඇಉظॲཧΛ࣮ߦ͢Δ͜ͱͰ
 ΑΓޮ཰తʹܭࢉΛߦ͏͜ͱ͕Ͱ͖Δ

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

Continuation (ܧଓ) w TVTQFOEؔ਺Ͱதஅ͞Εͨίϧʔνϯͷঢ়ଶ w தஅ͞Εͨ෦෼Ҏ߱ͷ࢒Γͷॲཧ ίʔϧόοΫ Λද͢ w SFTVNF8JUIϝιου͸׬ྃίʔϧόοΫͰ͋Γ
 ίϧʔνϯͷ׬ྃ࣌ʹ੒ޭɾࣦഊͷ͍ͣΕ͔Λฦ͢ public interface Continuation { public val context: CoroutineContext public fun resumeWith(result: Result) }

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

suspend fun susFunc( time: Long ) : String { delay(time) return "Kotlin Fest!" } TVTQFOEؔ਺

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

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

Slide 106

Slide 106 text

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

Slide 107

Slide 107 text

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

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

startCoroutine w ίϧʔνϯΛ࡞੒ͯ͠ݱࡏͷεϨουͰ
 ϨγʔόʔͰ͋ΔTVTQFOEϥϜμΛ࣮ߦ͢Δ w MBVODI BTZODͳͲͷίϧʔνϯϏϧμʔ΋
 ಺෦తʹݺͼग़ͯ͠ίϧʔνϯΛ࡞੒͍ͯ͠Δ public fun (suspend () -> T).startCoroutine( completion: kotlin.coroutines.Continuation ): kotlin.Unit { /* compiled code */ }

Slide 110

Slide 110 text

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

Slide 111

Slide 111 text

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

Slide 112

Slide 112 text

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

Slide 113

Slide 113 text

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

Slide 114

Slide 114 text

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

Slide 115

Slide 115 text

inline fun (suspend () -> T).startCoroutineUninterceptedOrReturn( completion: Continuation ): kotlin.Any? { /* compiled code */ } internal enum class CoroutineSingletons { COROUTINE_SUSPENDED, UNDECIDED, RESUMED } startCoroutineUninterceptedOrReturn w TUBSU$PSPVUJOFͱҧ͍ɺฦΓ஋Λड͚औΔ w ࣮ߦͨ͠TVTQFOEؔ਺͕಺෦ͷதஅ఺Ͱதஅ͞ΕΔͱ
 $03065*/&@4641&/%&%ϚʔΧʔΛฦ͢ ίϧʔνϯʹ౉͞Ε͍ͯΔ
 Continuation͸Ͳ͏΍ͬͯऔಘͰ͖Δʁ

Slide 116

Slide 116 text

suspendCoroutineUninterceptedOrReturn w ίϧʔνϯ಺ͰݺͿ͜ͱͰίϧʔνϯ͕தஅͨ͠࢒Γͷঢ়ଶΛ
 $POUJOVBUJPOΠϯελϯεͱͯ͠औಘͰ͖Δ"1* w ϥϜμࣜͰ$POUJOVBUJPOΠϯελϯεΛࢀর͠
 ίϧʔνϯͷதஅɾ׬ྃͱ͍ͬͨঢ়ଶΛ௚઀੍ޚͰ͖Δ suspend inline fun suspendCoroutineUninterceptedOrReturn( crossinline block: (Continuation) -> Any? ): T

Slide 117

Slide 117 text

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

Slide 118

Slide 118 text

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

Slide 119

Slide 119 text

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

Slide 120

Slide 120 text

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

Slide 121

Slide 121 text

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

Slide 122

Slide 122 text

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

Slide 123

Slide 123 text

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

Slide 124

Slide 124 text

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

Slide 125

Slide 125 text

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

Slide 126

Slide 126 text

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

Slide 127

Slide 127 text

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

Slide 128

Slide 128 text

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

Slide 129

Slide 129 text

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

Slide 130

Slide 130 text

suspendCoroutineUninterceptedOrReturn { continuation -> do { val rc = PhaseʹׂΓ౰ͯΒΕͨϥϜμࣜ. startCoroutineUninterceptedOrReturn(ɾɾɾ) ɾɾɾ } while (true) COROUTINE_SUSPENDED } w TVTQFOE$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOͱ
 TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOΛ૊Έ߹ΘͤΔ͜ͱͰ
 $POUJOVBUJPOΛڞ༗͠ͳ͕ΒίϧʔνϯΛ࡞੒͍ͯ͠Δ

Slide 131

Slide 131 text

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

Slide 132

Slide 132 text

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

Slide 133

Slide 133 text

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

Slide 134

Slide 134 text

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

Slide 135

Slide 135 text

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

Slide 136

Slide 136 text

private val continuation: Continuation = object : Continuation, 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>).last().context else -> throw IllegalStateException("e") } } }

Slide 137

Slide 137 text

private val continuation: Continuation = object : Continuation, 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>).last().context else -> throw IllegalStateException("e") } } }

Slide 138

Slide 138 text

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

Slide 139

Slide 139 text

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

Slide 140

Slide 140 text

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

Slide 141

Slide 141 text

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

Slide 142

Slide 142 text

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

Slide 143

Slide 143 text

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

Slide 144

Slide 144 text

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

Slide 145

Slide 145 text

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

Slide 146

Slide 146 text

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

Slide 147

Slide 147 text

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

Slide 148

Slide 148 text

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

Slide 149

Slide 149 text

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

Slide 150

Slide 150 text

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

Slide 151

Slide 151 text

·ͱΊ

Slide 152

Slide 152 text

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

Slide 153

Slide 153 text

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

Slide 154

Slide 154 text

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

Slide 155

Slide 155 text

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

Slide 156

Slide 156 text

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

Slide 157

Slide 157 text

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

Slide 158

Slide 158 text

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