はじめに
JSを学習するにあたり、非同期処理(Promise
、async
、await
等)について理解ができてないので簡単にまとめてみました。
「そもそも非同期処理って何??」って、最初は疑問をもつと思います。
なので、まずは概念的な部分からさぐっていき、JSの非同期処理の定番であるPromise
、async
、await
についてまとめていきます。
概念(同期処理、非同期処理)
同期処理
はプログラムを上から順に処理していくこと。ひとつの処理が完了するまで次の処理は行われません。
非同期処理
は同期処理とは違って、ひとつの処理を行っている間、別の処理を並行して行えます。
その2つの違いをわかりやすく日常的なことを取り入れて、図解にすると下の違いです。
同期処理 非同期処理
掃除 Netflixみる 掃除 Netflixみる
| |
| |
|ーーーーーー| |ーーーーーー|
中断 | 継続| |
| | |
|ーーーーーー| |ーーーーーー|
| |
| |
このようにみると、日常が非同期処理だと楽ですよね。同期処理とは違って、実行完了を待たずに処理を実行しています。
改めてJSが言う非同期処理とは
・Web API(通信が発生する処理)
・データベース通信
・実行完了を待たない
などの以上のことが可能です。
コードで簡単に記述していくと、
//非同期処理
console.log(1)
setTimeout(function() {
console.log(2)
},1000) //1秒後出力
console.log(3)
// 結果
1
3
2
と3の数字が先にきていることがわかります。
非同期通信メソッドである、fetch
を利用していく例だと、、
const fetchFunc = () => {
const url = '外部API(https://..........)'
// APIへの非同期処理
fetch(url).then(response => {
console.log("非同期処理が完了しました!")
return '完了'
})
.catch(() => {
console.error('非同期処理が失敗です。')
return '失敗!'
})
}
const message = '非同期処理'
const result = fetchFunc()
console.log(message + result)
// 結果
非同期処理undefined
非同期処理が完了しました!
fetchFunc
の結果がundefined
になり、message
とresult
を返した値が出ています。
また、fetch
メソッドは、url
が取得した値をresponse
で呼び出します。
良い面😆
ユーザーを待たせない(外部との通信に時間がかかる間に、ユーザーは別のことに取り掛かりたい)ということが挙げられますが、
悪い面😱
実行完了までにデータが存在しないということです。
例えば、Web APIを叩いた際に、レスポンスがまだ帰ってきてない時に実行完了すると、Web APIのデータが存在せず、レスポンスを待たずにタスクが完了してしまう。
上の例でいくと、APIの非同期処理が後から出力されていることがわかりますね。
その非同期処理を待つ方法としてあげられるのが、Promise
とasync
,await
です。
Promise
非同期処理の状態を表すオブジェクト
ちなみに日本語だと「約束」Promise
具体的にいうと、実行完了を待って値を渡してから、次の処理に移ります。
そして、Promiseの状態を表すのが、
・pending
:非同期処理の実行中の状態
・fulfilled
:処理が成功した状態 =(resolve()
メソッド)
・rejected
:処理が失敗した状態 =(rejected()
メソッド)
を表します。
非同期関数を書き換えてみると、、
// Promise
const promiseFunc = () => {
return new Promise((resolve,reject) => {
const url = '外部API(https://..........)'
fetch(url).then(() => {
console.log('このPromiseは完了しました!')
return resolve('完了')
}).catch(() => {
console.log('このPromiseは失敗しました!')
return reject
})
})
}
const message2 = 'Promise'
// 非同期処理を実行してthenでチェインする
promiseFunc().then(result => {
// resultは引数で、returnした値が帰ってくる(resolve)
console.log(message2 + result)
})
// 結果
このPromiseは完了しました!
Promise完了
return new Promise((resolve,reject) => {}
と記述することでPromiseができます。
コード中にも記述してありますが、関数名.then(引数 => {})
でチェインして、引数(実行結果)の値を取得します。
async,await
Promise
よりもわかりやすい記述で、直感的にわかりやすい。
日本語だと、「非同期」async
、「待つ」await
です。
それぞれの役割としては、
・async
非同期処理の関数定義につける
・await
〃 の実行関数につける
・また、await
はasync
の関数内でしか使えない
と行った具合になります。
// async await
const asyncFunc = async() => {
const message3 = 'async await'
const url = '外部API(https://..........)'
const hoge = await fetch(url).then(() => {
console.log('このasync,awaitは完了しました!')
return '完了'
}).catch(() => {
console.log('このasync,awaitは失敗しました!')
return '失敗'
})
console.log(message3 + hoge)
return
}
asyncFunc()
// 結果
このasync,awaitは完了しました!
async await完了
async
関数内で定義したことにより、fetch
メソッドの前にあるawait
が働くことによって、hogeという関数の処理が終わった後に、console.log
が出力されますね。
感想
Web APIを操作することを今後、やっていくとなると必ずぶち当たると思うので、要約してみました。async,awaitを少し触った程度の内容ですので、例外処理についてもアウトプットしていきたいです。
参考にさせていただいたサイト
https://tech.playground.style/javascript/asynchronous-processing/