今週は第57回を開催しました!
引き続きKotlin Hands-onをすすめています。
前回の様子はコチラ↓
[第57回の様子]
2021/3/24に第56回を開催した。
参加メンバーは自分をいれて3名。今回は久しぶりのメンバーも参加してくれた!
今回、自分はナビゲータ役で参加した。
勉強会本編の内容としては、ひき続きIntroduction to Coroutines and Channelsハンズオンを進めた。第6章 Structured Concurrency
を半分ほど進めた。
[学んだことや疑問点]
- Introduction to Coroutines and Channels: 6. Structured Concurrency
- Coroutine scopeの役割は異なるCoroutine間の親子関係を持たせること
- Coroutine contextにはcoroutineの名前やどのスレッドでcoroutineを実行すべきかといった追加の技術情報が含まれている
launch
やasync
によって、新しいcoroutineは常にcoroutine scopeの中でのみ開始できる:runBlocking
のみ例外的なトップレベル関数として定義されているlaunch
やasync
はCoroutineScope
の拡張関数なのでcoroutine scopeの中でのみ呼び出せる
import kotlinx.coroutines.* fun main() = runBlocking { /* ここでのthisはCoroutineScope */ launch { /* これはrunBlockingで開始されたCoroutineScopeの子供のスコープ */ } // 上の行は以下の行と同じ意味 this.launch { /* ... */ } }
coroutineScope()
関数を使うとcoroutineを開始することなくCoroutineScope
を作成できるsuspend
関数のなかで新しいcoroutineを使う場合にcoroutineScope()
関数を利用した(前回・前々回のloadContributorsConcurrent
関数がそれ:suspend
関数はcoroutine scopeの中で呼ばれるので、そのスコープの子供のスコープが作成される)GlobalScope.async()
やGlobalScope.launch()
で親子関係のない独立したcoroutine scopeを開始することもできる:独立しているので明示的にcoroutineへの参照を保持してキャンセルする必要がある- Coroutine Scopeに親子関係があることで以下の利点がある
- 親スコープが子のスコープを管理する、子の寿命は親の寿命に制限される
- 親スコープがキャンセルされると、子のcoroutineもキャンセルされる
- 親coroutineは子のcoroutineの完了を待つ
- ローディング処理をキャンセルする
- 前回実装した
loadContributorsConcurrent
をキャンセルしやすくするために、delay
処理を追加する
suspend fun loadContributorsConcurrent(service: GitHubService, req: RequestData): List<User> = coroutineScope { // ... async { log("starting loading for ${repo.name}") delay(3000) // load repo contributors } // ... result }
suspend fun loadContributorsConcurrent(service: GitHubService, req: RequestData): List<User> = { // ... GlobalScope.async { log("starting loading for ${repo.name}") delay(3000) // load repo contributors } // ... result }
- 動作確認をするぞ!というところで時間ぎれ....続きは次週!
[まとめ]
モブプログラミング・スタイルで、Introduction to Coroutines and Channelsハンズオンを進めた。
Coroutineのcontextとscopeの違い、scopeの親子関係とGlobalScopeなど、Structured Concurrencyについて理解を深められた!!
今週のプルリクエストはこちら。