非同期処理
待ち時間の間に他の仕事をする。
I/O(ネットワーク、ディスク)は CPU より 5〜6 桁遅い。 待っている間 UI を止めると、アプリが固まる。
表現の変遷#
| 形式 | 問題 |
|---|---|
| コールバック | ネストが深くなる。エラー処理が散らばる |
| Promise / Future | 連結できる。まだ手続き的でない |
| async / await | 同期コードのように書ける |
| リアクティブ (Rx, Combine) | ストリームとして扱う。学習コストが高い |
// コールバック
fetch(url, { data in parse(data, { result in show(result) }) })
// async/await
let data = try await fetch(url)
let result = try parse(data)
show(result)関数の色#
async な関数は async な文脈からしか呼べない。
この制約が呼び出し側へ伝播していく(関数の色問題)。
同期コードから非同期を呼ぶには
境界(Task、Promise の生成)が要る。
軽量スレッド方式
(Go、Java 仮想スレッド)はこの問題を回避している。
並行実行#
逐次: await a(); await b() … a が終わってから b
並行: async let x = a(); async let y = b(); await (x, y)独立した処理を逐次で待つのは無駄。 3 つの API を順に待つと 3 倍の時間がかかる。
中断とキャンセル#
画面を閉じたのに通信が続くのは資源の無駄。
- Swift の構造化並行性 — 親タスクの終了で子も取り消される
AbortController(Web)
開始したものを取り消せる設計にしておく。
参考文献#
- Swift Programming Language. Concurrency. https://docs.swift.org/swift-book/documentation/the-swift-programming-language/concurrency/
- MDN. Asynchronous JavaScript. https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Async_JS
- Bob Nystrom. What Color is Your Function? 2015. https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/