ECMAScript2017で導入された、async/awaitを利用すると、非同期処理を見通しよく書くことができます。ここでは、「async/awaitの使い方」「Promiseとの違い」を解説します。
サンプルソースで基本的な使い方を確認
まず、以下サンプルソースで動作確認してみます。
const func = () => {
// 非同期処理
asyncFunc()
// asyncFuncの結果を待たずに実行
console.log(3)
}
const asyncFunc = async () => {
const sleep = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve(1)
}, 2000)
})
}
const x = await sleep()
// sleepの結果を待ってから実行
console.log(x)
console.log(2)
}
func()
3
1
2
async
関数の前に、async
を付けると async関数
になります。 (今回だとasyncFunc関数)
asyncFunc関数の結果を待たずに、3が出力されています。
await
async関数内部では、sleep関数の前に await
が付けられています。
sleep関数の結果を待ってから、1, 2と出力されています。
つまり、 await
を付けると、非同期処理内部で処理が一時停止されます。
await
は、async関数の中でのみ使えます。await
を付けた関数が、Promiseの結果を返すまで、一時停止します。
ブラウザごとの対応状況を以下ページで確認できます
https://caniuse.com/#feat=async-functions
利用する場合、Babel等でトランスパイルの対応が必要か確認しておく必要があります。
エラー処理
async/await
は Promise
より、エラー処理の記述がわかりやすいと言われています。
どのようにわかりやすいのか確認します。
const sleep = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve(2)
}, 2000)
})
}
const syncFunc1 = () => {
console.log(1)
}
const syncFunc2 = () => {
console.log(3)
}
非同期処理のsleepと同期処理のsyncFunc1, syncFunc2を記述してます。
- Promiseで利用した場合
- async/awaitで利用した場合
を比較します。
Promiseの場合
const promiseFunc = () => {
try {
syncFunc1()
sleep().then(data => {
console.log(data)
syncFunc2()
}).catch((err) => {
console.log(err)
})
} catch (err) {
console.log(err)
}
}
promiseFunc()
以下目的で、 catch
が2回書かれています。
sleep(非同期処理)
の例外をキャッチするためsyncFunc1(同期処理)
の例外をキャッチするため
async/awaitの場合
const asyncFunc = async () => {
try {
syncFunc1()
console.log(await sleep())
syncFunc2()
} catch (err) {
console.log(err)
}
}
asyncFunc()
こちらは、 catch
が1回だけ書かれています。
1回のcatchで 同期処理(syncFunc1, syncFunc2)
と 非同期処理(sleep)
の例外をキャッチすることができます。
非同期処理の同時実行
await
で Promise.all
を利用することで、非同期処理を同時実行することができます。
const sleep = data => {
return new Promise(resolve => {
setTimeout(() => {
resolve(data)
}, 2000)
})
}
const asyncFunc = async () => {
const [x, y] = await Promise.all([
sleep(3), sleep(10)
])
console.log(x)
console.log(y)
}
asyncFunc()
3
10