モダンなjsではasyncFunctionで同期っぽく非同期処理を書きたいわけですが、
何でもかんでもawaitで止めて直列処理にしてしまうのが不適切な場合もあります。
例えば、以下のようなケースです。
- 非同期処理Bは画面を機能させるために必須の処理である。
- 非同期処理Bは非同期処理Aの結果に依存する。
- 非同期処理C及びDは必要な処理ではあるが、画面初期描画時に必須ではない
- 非同期処理Dは非同期処理Cの結果に依存する
この場合、画面を初期描画するのにBが必須なため、AとBに関してはasync functionの中で
const aResult = await a();
const bResult = await b(aResult);
//bResultを基に画面が描画される
と書けばOKです。
では、ここでCとDをどう書くか?
const aResult = await a();
const bResult = await b(aResult);
const cResult = await c();
const dResult = await d(cResult);
//bResultを基に画面が描画される
という風にとにかくawaitでつなげても動きはします。
が、こう書くと本来はaやbの待ち時間にc,dの処理を始められないため非効率的です。
というわけで、効率化を考えると、以下のようにc,d部分は以下のように書く必要があります。
c()
.then(cResult => d(cResult))
.then(dResult => {//dResultを使った処理});
const aResult = await a();
const bResult = await b(aResult);
cとdに依存性がなければ
c();
d();
const aResult = await a();
const bResult = await b(aResult);
と書いて終わりですが、cとdは直列化しないといけない場合は、thenでつなぐ必要があります。
が、せっかくasyncなのにここでthenが出てくるのはちょっと格好悪い気がします。
無名async関数
(async() => {
const cResult = await c();
const dResult = await d(cResult);
//dResultを使った処理
})();
const aResult = await a();
const bResult = await b(aResult);
asyncは無名関数でも問題なく利用でき、即時実行すればPromiseを返してくれます。
処理が長かったり、他でも使う場合は関数として切り出した方が良いと思いますが、
他で使う予定がない処理の場合ささっと無名関数で書いてしまうのもアリだと思います。