Slide 1

Slide 1 text

ౙٳΈલʹ ,PUMJOͷ$PSPVUJOFTΛ ٵҾ͍ͨ͠ਓ͕ू͏ձ !V[[V

Slide 2

Slide 2 text

झࢫ w೥຤,PUMJOͰ੒Ռग़ͧ͢ w·ͩ$PSPVUJOFTΑ͘෼͔ͬͯͳ͍ͧ w$PSPVUJOFTରԠਓࡐʹͳΔͧ

Slide 3

Slide 3 text

ຊ୊ w ,PUMJOϕʔεͰ࿩͠·͢  w$PSPVUJOFTͱ͸ wଞݴޠʹ͓͚ΔBTZODBXBJUͱͷҧ͍ w࢖͍ํͬ͘͟Γ wͱΓ͜ΕϦϯΫू

Slide 4

Slide 4 text

$PSPVUJOFT w,PUMJO͔Βਖ਼ࣜϦϦʔε͞Εͨඇಉظϓϩάϥ ϛϯάͷҝͷػೳ ΋ͪΖΜNVMUJQMBUGPSNରԠ  wଞݴޠͰ͍͏ॴͷBTZODBXBJU౳ؚ͕·Ε͍ͯΔ wଞݴޠͰ͍͏ॴͷDPSPVUJOF HFOFSBUPS ͸
 ,PUMJOͰ͸4FRVFODF5

Slide 5

Slide 5 text

BTZODBXBJU $ class Program { static async ValueTask DoSomething(int value) { await Task.Delay(1000); return value * value; } static async Task MainAsync(string[] args) { Console.WriteLine("Start task"); var result = await DoSomething(100); Console.WriteLine($"Result: {result}"); } static void Main(string[] args) => MainAsync(args).Wait(); }

Slide 6

Slide 6 text

BTZODBXBJU $ class Program { static async ValueTask DoSomething(int value) { await Task.Delay(1000); return value * value; } static async Task MainAsync(string[] args) { Console.WriteLine("Start task"); var result = await DoSomething(100); Console.WriteLine($"Result: {result}"); } static void Main(string[] args) => MainAsync(args).Wait(); }

Slide 7

Slide 7 text

BTZODBXBJU $ class Program { static async ValueTask DoSomething(int value) { await Task.Delay(1000); return value * value; } static async Task MainAsync(string[] args) { Console.WriteLine("Start task"); var result = await DoSomething(100); Console.WriteLine($"Result: {result}"); } static void Main(string[] args) => MainAsync(args).Wait(); }

Slide 8

Slide 8 text

BTZODBXBJU &4 function sleep(milliSeconds) { return new Promise(resolve => setTimeout(resolve, milliSeconds)); } async function doSomething(value) { await sleep(1000); return value * value; } (async() => { console.log("Start task."); const result = await doSomething(100); console.log(`Result: ${result}`) })();

Slide 9

Slide 9 text

BTZODBXBJU &4 function sleep(milliSeconds) { return new Promise(resolve => setTimeout(resolve, milliSeconds)); } async function doSomething(value) { await sleep(1000); return value * value; } (async() => { console.log("Start task."); const result = await doSomething(100); console.log(`Result: ${result}`) })();

Slide 10

Slide 10 text

BTZODBXBJU &4 function sleep(milliSeconds) { return new Promise(resolve => setTimeout(resolve, milliSeconds)); } async function doSomething(value) { await sleep(1000); return value * value; } (async() => { console.log("Start task."); const result = await doSomething(100); console.log(`Result: ${result}`) })();

Slide 11

Slide 11 text

BTZODBXBJU wBTZODGVODUJPOΛ࣮૷ͯ͠
 ݺͼग़͠ଆͰBXBJU͢Δ

Slide 12

Slide 12 text

$PSPVUJOFT suspend fun doSomething(value: Int): Int { delay(1000) return value * value } fun main() = runBlocking { println("Start task") val result = doSomething(100) println("Result: $result") }

Slide 13

Slide 13 text

$PSPVUJOFT suspend fun doSomething(value: Int): Int { delay(1000) return value * value } fun main() = runBlocking { println("Start task") val result = doSomething(100) println("Result: $result") }

Slide 14

Slide 14 text

$PSPVUJOFT suspend fun doSomething(value: Int): Int { delay(1000) return value * value } fun main() = runBlocking { println("Start task") val result = doSomething(100) println("Result: $result") }

Slide 15

Slide 15 text

$PSPVUJOFT wTVTQFOEGVODUJPOΛ࣮૷ͯ͠
 ݺͼग़͠ଆ͸ͨͩݺͿ BXBJULFZXPSEͳ͠ 
 BTZODBXBJUͳݴޠͰ͸ඇಉظͰ͋Δࣄ͕લఏ
 ,PUMJOͰ͸ඇಉظؔ਺Ͱ͸ͳ͘தஅؔ਺ͳͷͰ
 ɹಉظzతzʹهड़Ͱ͖ΔΑ͏ʹͳ͍ͬͯΔ
 ɹଞݴޠͷΑ͏ʹಉظඇಉظΛҙࣝ͢Δඞཁ͕ͳ͍

Slide 16

Slide 16 text

࢖͍ํ w%FQFOEFODJFTͷ௥Ճ w$PSPVUJOF4DPQFΛ࣮૷͢Δ w$PSPVUJOF4DPQFMBVODIͯ͠
 Α͠ͳʹTVTQFOEGVODUJPOΛݺͼग़͢

Slide 17

Slide 17 text

%FQFOEFODJFTͷ௥Ճ w,PUMJOdΛೖΕΔ͚ͩͰ͸࣮࣭࢖͑ͳ͍
 ݴޠͱͯ͠͸௿ϨΠϠʔͳ࢓༷ͷΈಉ͍ࠝͯ͠Δҝ 
 wՃ͑ͯɺ1MBUGPSNʹ߹ΘͤͯϥΠϒϥϦΛ௥Ճ
 implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.1" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.1"

Slide 18

Slide 18 text

$PSPVUJOF4DPQFΛ࣮૷͢Δ wTVTQFOEGVODUJPO͸$PSPVUJOFͷத͋Δ͍͸ TVTQFOEGVODUJPO͔ΒͷΈར༻Ͱ͖Δ w$PSPVUJOF͸$PSPVUJOF4DPQFͷதͰͷΈ
 ىಈͰ͖Δ w$PSPVUJOF4DPQFͷ࣮૷͕ඞཁ

Slide 19

Slide 19 text

$PSPVUJOF4DPQFΛ࣮૷͢Δ suspend fun doSomething(value: Int): Int { delay(1000) return value * value } fun main() = runBlocking { println("Start task") val result = doSomething(100) println("Result: $result") } ݱࡏͷ࣮ߦεϨουΛݩʹ CoroutineScopeΛ࡞ͬͯ ࣮ߦ׬ྃ·Ͱ଴ͬͯΔ

Slide 20

Slide 20 text

$PSPVUJOF4DPQFΛ࣮૷͢Δ w࣮૷ͷલʹগ͚ͩ͠ొ৔ਓ෺ͷ੔ཧ
 ਂೖΓ͢ΔͱऴΘΒͳ͍ͷͰগ͚ͩ͠

Slide 21

Slide 21 text

࣮૷͢Δ্Ͱ࠷௿ݶͷొ৔ਓ෺ w$PSPVUJOF$POUFYUϓϩύςΟͱͯ࣋ͭ͠ඞཁ͕͋Δ w+PCMBVODI͢Δ$PSPVUJOFͷϥΠϑαΠΫϧΛ؅ཧ w$PSPVUJOF%JTQBUDIFS࣮ߦίϯςΩετ 5ISFBEFUD  wଞɺ$PSPVUJOF&YDFQUJPO)BOEMFS౳͍Δ
 ͕Ұ୴์ஔ

Slide 22

Slide 22 text

$PSPVUJOF4DPQFΛ࣮૷͢Δ class SimpleCoroutineScope(ui: CoroutineDispatcher) : CoroutineScope { // ਌JobΛ࡞Δ(࡞Ε) private val job: Job = Job() // σϑΥϧτͷڍಈͱͯ͠
 // ਌Job͸jobϓϩύςΟͷ΍ͭ
 // ࣮ߦίϯςΩετ͸ίϯετϥΫλҾ਺uiΛ༻͍Δ override val coroutineContext: CoroutineContext = job + ui }

Slide 23

Slide 23 text

$PSPVUJOF4DPQFΛ࣮૷͢Δ class SimpleCoroutineScope : CoroutineScope { // ਌JobΛ࡞Δ(࡞Ε) private val job: Job = Job() // σϑΥϧτͷڍಈͱͯ͠
 // ਌Job͸jobϓϩύςΟͷ΍ͭ
 // ࣮ߦίϯςΩετ͸mainϧʔϓΛ༻͍Δ override val coroutineContext: CoroutineContext = job + Dispatchers.Main }

Slide 24

Slide 24 text

$PSPVUJOF4DPQFΛ࣮૷͢Δ class SimpleCoroutineScope : CoroutineScope { // ਌JobΛ࡞Δ(࡞Ε) private val job: Job = Job() // σϑΥϧτͷڍಈͱͯ͠
 // ਌Job͸jobϓϩύςΟͷ΍ͭ
 // ࣮ߦίϯςΩετ͸IO Pool(※Threadͱ͸ݶΒͳ͍)Λ༻͍Δ override val coroutineContext: CoroutineContext = job + Dispatchers.IO }

Slide 25

Slide 25 text

$PSPVUJOF4DPQFMBVODI͢Δ w جຊతͳॴͱͯ͠ MBVODI͢Δͱ$PSPVUJOF͕ى ಈ͢Δ
 $PSPVUJOF͸࣮ࡍ͍ΖΜͳॴͰىಈ͍ͯ͠Δ͚Ͳলུ wMBVODIͷલʹొ৔ਓ෺Λʜ

Slide 26

Slide 26 text

ొ৔ਓ෺ w$PSPVUJOF4DPQF͖ͬ͞࡞ͬͨ΍ͭ w$PSPVUJOF$POUFYU͖ͬ͞ϓϩύςΟʹ࣋ͨͤͨ΍ͭ w$PSPVUJOFMBVODI౳ʹΑͬͯ࡞ΒΕΔ࣮ࡍʹಈ͍ͯΔ΍ͭ w+PC  ུ %JTQBUDIFS FUDʜ͖ͬ͞આ໌ͨ͠΍ͭ wଞɺ$PSPVUJOF4UBSU౳͋Δ͕Ұ୴লུ

Slide 27

Slide 27 text

$PSPVUJOF4DPQFMBVODI͢Δ class SimpleCoroutineScope : CoroutineScope { // ਌JobΛ࡞Δ(࡞Ε) private val job: Job = Job() // σϑΥϧτͷڍಈͱͯ͠
 // ਌Job͸jobϓϩύςΟͷ΍ͭ
 // ࣮ߦίϯςΩετ͸mainϧʔϓΛ༻͍Δ override val coroutineContext: CoroutineContext = job + Dispatchers.Main }

Slide 28

Slide 28 text

$PSPVUJOF4DPQFMBVODI͢Δ class SimpleCoroutineScope : CoroutineScope { private val job: Job = Job() override val coroutineContext: CoroutineContext = job + Dispatchers.Main fun foo() { launch { // ਌Λjob // ࣮ߦίϯςΩετΛmainϧʔϓͱͯ͠ // CoroutineΛىಈ͠ॲཧΛ࣮ߦ͢Δ val result = doSomething() } } }

Slide 29

Slide 29 text

$PSPVUJOF4DPQFMBVODI͢Δ class SimpleCoroutineScope : CoroutineScope { // ਌JobΛ࡞Δ(࡞Ε) private val job: Job = Job() // σϑΥϧτͷڍಈͱͯ͠
 // ਌Job͸jobϓϩύςΟͷ΍ͭ
 // ࣮ߦίϯςΩετ͸IO Pool(※Threadͱ͸ݶΒͳ͍)Λ༻͍Δ override val coroutineContext: CoroutineContext = job + Dispatchers.IO }

Slide 30

Slide 30 text

$PSPVUJOF4DPQFMBVODI͢Δ class SimpleCoroutineScope : CoroutineScope { private val job: Job = Job() override val coroutineContext: CoroutineContext = job + Dispatchers.IO fun foo() { launch { // ਌Λjob // ࣮ߦίϯςΩετΛIO Poolͱͯ͠ // CoroutineΛىಈ͠ॲཧΛ࣮ߦ͢Δ val result = doSomething() } } }

Slide 31

Slide 31 text

$PSPVUJOF4DPQFMBVODI͢Δ wิ଍ɿ͜Ε͸DPNQJMFFSSPS SFUVSOͰ͖ͳ͍ fun execute(): Int { launch { return doSomething() } }

Slide 32

Slide 32 text

TVTQFOEGVODUJPOΛ࣮૷͢Δ suspend fun doSomething(value: Int): Int { delay(1000) return value * value } fun main() = runBlocking { println("Start task") val result = doSomething(100) println("Result: $result") }

Slide 33

Slide 33 text

TVTQFOEGVODUJPOΛ࣮૷͢Δ suspend fun doSomething(value: Int): Int { delay(1000) return value * value } fun main() = runBlocking { println("Start task") val result = doSomething(100) println("Result: $result") } ͜Εsuspend function

Slide 34

Slide 34 text

TVTQFOEGVODUJPOΛ࣮૷͢Δ function sleep(milliSeconds) { return new Promise(resolve => setTimeout(resolve, milliSeconds)); } async function doSomething(value) { await sleep(1000); return value * value; } (async() => { console.log("Start task."); const result = await doSomething(100); console.log(`Result: ${result}`) })();

Slide 35

Slide 35 text

TVTQFOEGVODUJPOΛ࣮૷͢Δ function sleep(milliSeconds) { return new Promise(resolve => setTimeout(resolve, milliSeconds)); } async function doSomething(value) { await sleep(1000); return value * value; } (async() => { console.log("Start task."); const result = await doSomething(100); console.log(`Result: ${result}`) })(); Ԟ஍Ͱ͜Ε૬౰ͷͳʹ͔Λ
 ࣮૷͢Δඞཁ͕͋Δ

Slide 36

Slide 36 text

TVTQFOEGVODUJPOΛ࣮૷͢Δ w࣮૷ͷલʹొ৔ਓ෺Λʜ

Slide 37

Slide 37 text

TVTQFOEGVODUJPOΛ࣮૷͢Δ wTVTQFOE$PSPVUJOFTVTQFOEGVODUJPOΛ࣮૷͢Δҝͷ ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ#VJMEFSGVODUJPO w$POUJOVBUJPOTVTQFOEGVODUJPOΛ࠶։͢Δҝͷ&NJUUFSɹ wଞɺTVTQFOE $PSPVUJOFɺ $POUJOVBUJPO
 γϦʔζ͕͍͔ͭ͋͘Δ͚ͲҰ୴লུ

Slide 38

Slide 38 text

TVTQFOEGVODUJPOΛ࣮૷͢Δ suspend fun doSomething(value: Int): Int = suspendCoroutine { continuation -> continuation.resume(value * value) } suspend fun doSomething(value: Int): Int = suspendCoroutine { continuation -> continuation.resumeWithException(Throwable()) }

Slide 39

Slide 39 text

طଘίʔυΛTVTQFOEGVO w$14 ͍ΘΏΔDBMMCBDLܗࣜ ͔ΒҠߦ͍ͨ͠৔߹ fun doSomethingAsync(value: Int, listener: Listener) { if (value <= 0) { listener.onError(Throwable()) } else { listener.onSuccess(value) } } suspend fun doSomething(value: Int): Int = suspendCoroutine { doSomethingAsync(value, object : Listener { override fun onSuccess(value: Int) { it.resume(value) } override fun onError(e: Throwable) { it.resumeWithException(e) } }) }

Slide 40

Slide 40 text

طଘίʔυΛTVTQFOEGVO w3FBDUJWFd͔ΒҠߦ͍ͨ͠৔߹͸ม׵༻ϥΠϒϥϦΛ࢖͏
 ҎԼ͸3Y+BWBͷྫ 
 fun doSomethingSingle(value: Int): Single = Single.just(value * value) suspend fun doSomething(value: Int): Int = doSomethingSingle(value).await() implementation "org.jetbrains.kotlinx:kotlinx-coroutines-rx2:1.0.1"

Slide 41

Slide 41 text

ྫ֎र͍͍ͨ launch { try { val result = doSomething() } catch (e: Throwable) { // } } launch { runCatching { doSomething() } // Result͕ฦ٫͞ΕΔ .onSuccess { value -> } .onFailure { throwable -> } } ,PUMJO͔Β௥ՃͷSVO$BUDIJOHਪ঑

Slide 42

Slide 42 text

࣮ߦίϯςΩετม͍͑ͨ class SimpleCoroutineScope : CoroutineScope { private val job: Job = Job() override val coroutineContext: CoroutineContext = job + Dispatchers.Main fun execute() { launch { // Main runCatching { // Main withContext(Dispatchers.IO) { // IO doSomething() } } .onSuccess { value -> // Main } .onFailure { throwable -> // Main } } } }

Slide 43

Slide 43 text

Ωϟϯηϧ͍ͨ͠ $ static async ValueTask DoSomething(int value, CancellationToken token) { await Task.Delay(1000); token.ThrowIfCancellationRequested(); return value * value; } static async Task MainAsync(string[] args) { Console.WriteLine("Start task"); var cancellable = new CancellationTokenSource(); var task = DoSomething(100, cancellable.Token); cancellable.Cancel(); var result = await task; Console.WriteLine($"result: {result}"); }

Slide 44

Slide 44 text

Ωϟϯηϧ͍ͨ͠ &4 async function doSomething(value, token) { await sleep(1000); await token.rejectIfCancelled(); return value * value; } (async() => { const cancellable = new Cancellable(); const finalize = () => cancellable.cancel(); process.on('exit', finalize); console.log("Start task."); doSomething(100, cancellable.token); console.log(`Result: ${result}`); process.removeListener('exit', finalize); })(); Cancellable.js https://gist.github.com/uzzu/7d6e89fafc4bcde1c6f6d82a3d164409 ˢ͸ྫ͕ѱ͍͕OPEFͰϓϩηεؒ௨৴ͭͭ͠௕ظλεΫ࣮ߦͯͯ͠ʜͳ࣌ͱ͔

Slide 45

Slide 45 text

Ωϟϯηϧ͍ͨ͠ class SimpleCoroutineScope : CoroutineScope { private val job: Job = Job() override val coroutineContext: CoroutineContext = job + Dispatchers.Main fun onDestroy() { job.cancel() } }

Slide 46

Slide 46 text

Ωϟϯηϧ͍ͨ͠ class SimpleCoroutineScope : CoroutineScope { private val job: Job = Job() override val coroutineContext: CoroutineContext = job + Dispatchers.Main fun onDestroy() { job.cancel() } } ࢠͷJob(Coroutine)͕શ෦cancel͞ΕΔ ݸผʹcancel͍ͨ͠έʔεʹ͍ͭͯ͸লུ

Slide 47

Slide 47 text

ͱΓ͜ΕϦϯΫू w$PSPVUJOF(VJEF
 IUUQTHJUIVCDPN,PUMJOLPUMJOYDPSPVUJOFTCMPC NBTUFSDPSPVUJOFTHVJEFNE
 ೔ຊޠ༁IUUQTHJUIVCDPNQMKQLPUMJOYDPSPVUJOFTCMPC KBQBOFTF@USBOTMBUJPODPSPVUJOFTHVJEFNE w,PUMJO$POGͰࢀՃͨ͠XPSLTIPQ
 IUUQTHJUIVCDPNFMJ[BSPW$PSPVUJOFT8PSLTIPQ
 ຊ౰ʹॳาతͳॴ͔Β"DUPS 1SPEVDFS·Ͱ෼͔Δ

Slide 48

Slide 48 text

Ұ୴͜͜·Ͱ

Slide 49

Slide 49 text

ଞτϐοΫฉ͖͍ͨࣄ͋Ε͹ޙ΄ͲͲ͏ͧ w "EWBODFE
 3Y+BWBΛར༻࣮ͨ͠૷ͱͷൺֱΛͯ͠ΈΑ͏
 TVTQFOEGVODUJPOΛෳ਺૸Β͍ͤͨBTZODͷར༻ํ๏ͱ஫ҙ఺
 +BWBίʔυͱͷ૬ޓӡ༻
 .VUFY
 ଟॏݺͼग़͠๷ࢭIPUMBVODI IPUTVTQFOEGVODUJPO ໋໊͸ద౰ 
 6OJU5FTUͷॻ͖ํ
 $PSPVUJOF4UBSU $PSPVUJOF&YDFQUJPO)BOEMFS TVTQFOE$PSPVUJOF$POUJOVBUJPOγϦʔζ 
 ଞඈ͹ౕͨ͠
 $IBOOFM "DUPS 1SPEVDFS w %FFQ%JWJOH
 KPC EJTQBUDIFS  ʜ ͬͯԿ
 ͲΜͳίʔυʹͳΔͷόΠτίʔυݟͳ͕Β
 $PSPVUJOFͷத਎Ͳ͏ͳͬͯΜͷιʔείʔυಡΈͳ͕Β
 NVMUJQMBUGPSNؔ࿈