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

Coroutine Kyuin

uzzu
December 20, 2018

Coroutine Kyuin

社内勉強会「冬休み前にKotlinのCoroutinesを吸引したい人が集う会」資料

uzzu

December 20, 2018
Tweet

More Decks by uzzu

Other Decks in Technology

Transcript

  1. BTZODBXBJU $ class Program { static async ValueTask<int> 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(); }
  2. BTZODBXBJU $ class Program { static async ValueTask<int> 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(); }
  3. BTZODBXBJU $ class Program { static async ValueTask<int> 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(); }
  4. 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}`) })();
  5. 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}`) })();
  6. 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}`) })();
  7. $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") }
  8. $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") }
  9. $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") }
  10. $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Λ࡞ͬͯ ࣮ߦ׬ྃ·Ͱ଴ͬͯΔ
  11. $PSPVUJOF4DPQFΛ࣮૷͢Δ class SimpleCoroutineScope(ui: CoroutineDispatcher) : CoroutineScope { // ਌JobΛ࡞Δ(࡞Ε) private

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

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

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

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

    job: Job = Job() // σϑΥϧτͷڍಈͱͯ͠
 // ਌Job͸jobϓϩύςΟͷ΍ͭ
 // ࣮ߦίϯςΩετ͸IO Pool(※Threadͱ͸ݶΒͳ͍)Λ༻͍Δ override val coroutineContext: CoroutineContext = job + Dispatchers.IO }
  17. $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() } } }
  18. 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") }
  19. 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
  20. 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}`) })();
  21. 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}`) })(); Ԟ஍Ͱ͜Ε૬౰ͷͳʹ͔Λ
 ࣮૷͢Δඞཁ͕͋Δ
  22. TVTQFOEGVODUJPOΛ࣮૷͢Δ suspend fun doSomething(value: Int): Int = suspendCoroutine { continuation

    -> continuation.resume(value * value) } suspend fun doSomething(value: Int): Int = suspendCoroutine { continuation -> continuation.resumeWithException(Throwable()) }
  23. طଘίʔυΛ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) } }) }
  24. طଘίʔυΛTVTQFOEGVO w3FBDUJWFd͔ΒҠߦ͍ͨ͠৔߹͸ม׵༻ϥΠϒϥϦΛ࢖͏
 ҎԼ͸3Y+BWBͷྫ 
 fun doSomethingSingle(value: Int): Single<Int> = Single.just(value

    * value) suspend fun doSomething(value: Int): Int = doSomethingSingle(value).await() implementation "org.jetbrains.kotlinx:kotlinx-coroutines-rx2:1.0.1"
  25. ྫ֎र͍͍ͨ launch { try { val result = doSomething() }

    catch (e: Throwable) { // } } launch { runCatching { doSomething() } // Result<T>͕ฦ٫͞ΕΔ .onSuccess { value -> } .onFailure { throwable -> } } ,PUMJO͔Β௥ՃͷSVO$BUDIJOHਪ঑
  26. ࣮ߦίϯςΩετม͍͑ͨ 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 } } } }
  27. Ωϟϯηϧ͍ͨ͠ $ static async ValueTask<int> 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}"); }
  28. Ωϟϯηϧ͍ͨ͠ &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Ͱϓϩηεؒ௨৴ͭͭ͠௕ظλεΫ࣮ߦͯͯ͠ʜͳ࣌ͱ͔
  29. Ωϟϯηϧ͍ͨ͠ class SimpleCoroutineScope : CoroutineScope { private val job: Job

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

    = Job() override val coroutineContext: CoroutineContext = job + Dispatchers.Main fun onDestroy() { job.cancel() } } ࢠͷJob(Coroutine)͕શ෦cancel͞ΕΔ ݸผʹcancel͍ͨ͠έʔεʹ͍ͭͯ͸লུ
  31. ଞτϐοΫฉ͖͍ͨࣄ͋Ε͹ޙ΄ͲͲ͏ͧ 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ؔ࿈