この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
おばんです、iOSDCの賞品であるtv 4kがちょうど手元に届いた田中です。しっかり開発して遊ぼうと思います。(オススメの4kディスプレイ情報お待ちしています)
さて、非同期処理周りのコードを簡潔に書きたいという気持ちから、業界的にPromiseが親しまれて久しい今日この頃。みなさまasync/awaitの方は使っておりますでしょうか。僕はちょうど最近触る機会があったので、今回はasync/awaitを使うと何が良いのか、これまであったPromiseと比較しながら紹介していこうと思います。
ネストが浅くなる
以下のコードを見比べてください。非同期処理ではなく、単純なサンプルですがPromiseの方はPromiseオブジェクトを生成してその中でresolveとrejectを返す必要があるため、一段ネストが深くなっています。async/awaitではそうなっていません。
ネストが浅いとコードは読みやすくなります。僕がasync/awaitを好む一つ目の理由がこれです。
Promise
const promiseFunction = () => {
return new Promise((resolve, reject) => {
resolve('hoge')
})
}
async/await
const asyncAwaitFunction = async () => {
return await 'hoge'
}
(見かけ上)Promiseオブジェクトのやりとりがなくなる
Promiseで非同期の関数を繋げて扱う場合、それぞれの関数で返却する値はPromiseオブジェクトにしなければいけないため、毎度 return new Promise()
しなければならなくなります。(前述した通り、この書き方をするとネストが深くなり、読みやすさが減ります。)
また、成功時の処理は .then
で扱う必要があります。コールバック地獄を扱うよりははるかに良くなっていますが、パッと見たときにコードが込み入っている印象を受けるかもしれません。(※個人の感想です。)
以下は非同期処理ではありませんが、Promiseとasync/awaitをシンプルに比較したコードです。
Promise
const promise1 = (num) => {
return new Promise(resolve => {
resolve(num + 1)
})
}
const promise2 = (num) => {
return new Promise(resolve => {
resolve(num + 2)
})
}
const promise3 = (num) => {
return new Promise(resolve => {
resolve(num + 3)
})
}
const promise = promise1(0)
.then(num => {
return promise2(num)
})
.then(num => {
return promise3(num)
})
.then(num => {
console.log(num)
})
.catch(error => {
console.log(error)
})
// 6 <- コンソールに出力される
async/await
そのまま変数として扱えるような見た目になります。async functionは暗黙的にPromiseオブジェクトを返却していて、 .then
の扱いはそのPromiseオブジェクトの返却した値で解決されるようです。(詳しくはこちら)
const asyncAwait1 = async (num) => {
return await num + 1
}
const asyncAwait2 = async (num) => {
return await num + 2
}
const asyncAwait3 = async (num) => {
return await num + 3
}
const asyncAwait = async () => {
const aa1 = await asyncAwait1(0)
const aa2 = await asyncAwait2(aa1)
const aa3 = await asyncAwait3(aa2)
const sum = aa3
console.log(aa3)
}
asyncAwait().catch(error => { console.log(error) })
// 6 <- コンソールに出力される
注意点
async/awaitはES7から採用される機能です。ウェブフレームワークとブラウザがES7に対応しているかどうかを確認しましょう。
まとめ
- Promiseオブジェクトを明示的に返却する必要がなくなるので、ネストが浅くなる
- thenでのやり取りがなくなる
この結果としてコードは読みやすくなり、行数も短く書くことができるようになります。コードを簡潔にわかりやすく書くのは正義です。async/awaitを使える環境にある場合、積極的に使っていきましょう。