Developers Summit 2016で非同期処理について話してきました

だいぶ間が空いてしまったんですが、デブサミ 2016 で非同期処理について話してきました。

event.shoeisha.jp

トピックとしてものすごく突出してたので成立するか不安だったのですが、なんとなく結論めいたものはでました。

詳しくは takezoe さんのブログを見て頂けると良いかと思います。

takezoe.hatenablog.com

結論みたいなもの

まぁやっぱり同期処理と非同期処理は『意識して使い分けなくても言語なりフレームワークなりで吸収するようになっていくんじゃないか』というのが1つの結論のような形になった。ES.Nextの async/await はその1つの形だと思う。"意識しないで"というのは難しいが、ほとんど同期処理と変わらない形で書けるようになる。

Node.js は coreの中でも Promise を採用するように只今構想中だし、ユーザーランドの場合はPromiseからの async/await への移行はそこまで難しくないように思える。

ただし、async/awaitやPromiseは 所謂単発モノと言われる、一回呼んだら非同期で返ってくるのが基本の処理だ。これでほとんどの処理はまかなえるかもしれないが、一回呼んだだけでは終わらないものも中にはある、時系列的に連続で発生する系の非同期イベントだ。

この『時系列的に連続で発生する類のもの』をどうやって扱うのかというのの1つの解が Stream のような data を chunk として扱って連続的に read / write するタイプの API だったり、 さらにそれを抽象化した Rx と呼ばれるライブラリだったりするんだろうと思う。

Stream については Chrome の開発をしている Jake がわかりやすい図を書いてくれているので引用する。

jakearchibald.com



Without streamingProcessRenderFetchWith streaming

この図はfetchの処理をする時にいっぺんに取得する時とchunk化して少しずつ取得する時の動きの違いをvisualizationしたものだが、わかりやすい違いが見えてるんじゃないかなと思う。

こういう処理をするような場合には非同期処理はさらに一歩先に進み、同期処理とは一線を画するモノになっていくと思う。単発モノの非同期処理を非同期処理レベル1とすると、こういう連続的なイベントを扱わなくてはいけないような非同期処理は非同期処理レベル2とも言える。

レベル1の非同期処理は同期処理とは変わらない形で書けるようになっていくとは思うが、レベル2の非同期処理はそもそも扱っているものの性質がこれまでの同期処理とは違うので『違いを意識しないで書く』というのは難しい気がする。

ただ幸いなことに現実的に今のサーバーサイドではそこまで連続的なイベントを扱うような事は経験上まだ少ない。僕が経験した所で言うと、 socket.io を使ったゲームだったり、いわゆるリアルタイムなウェブアプリを書くっていうような処理をした時に経験したくらいだ。

『サーバーサイドでは』と言及したが、クライアント側では割と頻繁に起きていると思う。クライアント側は非同期処理が複雑化しやすく、例えば Ctrl-x, Ctrl-s で保存するタイプのmarkdown editor を書きたいと思ったらそこそこ複雑なイベントハンドリングを求められる。ただの click イベントで発火するだけの処理を書いてる状況ではなくなっている。

そういう意味ではサーバー側もクライアント側も今後アプリケーションが複雑化してくる事を見越して非同期処理を意識して書いてみるのも良いのではないだろうか。

会場から来た質問

Q. 非同期処理と例外はどうしたらいいのか
A. JavaScript に関して言えば、今はPromiseにくるんで返すというのが一般的になっている、callback の第一引数に error を返してた時代から Promise の catch 関数でキャッチできるようになる時代はもう今来ている。更に進んで async/await になれば try/catch で例外を処理できる時代が来る、そこまで来ればあまり困らないはず。ただし、連続したイベントを扱うようなケースはまたちょっと趣が異なる。

Q. 非同期処理が廃れて同期処理だけで書ける未来は来ないのか
A. なくならないと思われる、昨今のアプリケーションでは外部APIを叩く場合やDBにアクセスする、S3にアクセスするなどのネットワーク経由で処理する事が多い。そのネットワークを経由する際にレイテンシが発生する。そうするとそのレイテンシを愚直に待つよりも非同期処理にして別タスクを実行するほうが効率が良いし、このレイテンシはどんなに速くなったとしても光の速さを超えられないので、どうしても厳しい。

最後にNode.jsの話を

非同期処理がわかりにくいとかそういう話は色々あると思いますが、一回Node.jsやってみるとわりとわかりやすくて良いんじゃないかなと自分では思っていますステマとかじゃなくて、非同期処理しかないという環境に入れられると否応なくその書き方に慣れます。callback地獄とか言われてるような処理に陥らないように工夫すると上で書いたような話もわかってくるんじゃないかなと。

なので、非同期処理を学びたければ、ぜひ一度Node.jsを!!