前置き
今回はasync/await
でPromise
の役割をするawait
についてです💫
2つのパターンについて書いていきます。
・await
でawait
をネスト
・await
で.then
のメソッドチェーン
そもそも今までの記事ではconst res = axios.get
みたいな取得した値を定数にして
その後で取得した値が返ってきた時の
処理を書いていました。
なのでそれ以外の使い方、
定数を使わなくても良い書き方が
すごく変に感じていたのです。。。
例えばfirebaseAuthで
アカウントを作成した後にdispatch
したい場合
こんな感じのコードになります👇
1 2 3 4 5 6 7 8 9 10 11 12 13 |
export const actions = { async register({ dispatch }, payload) { try { await this.$fire.auth.createUserWithEmailAndPassword( payload.email, payload.password ) dispatch('checkLogin') } catch (error) { console.log(error) //eslint-disable-line } }, } |
これをもしconst res = await
にしてしまうとそれ以降res
を使用する必要がないため、
どうすれば良いのか
分からなかったのです🤔💭
ただこの2つのパターンを理解すれば
簡単ということが分かりました❣️☝️
ということでLet's Go❗️
⬇️Promise
async/await
簡単な使い方などは
こちらをご覧ください🍀
【Nuxt.js】非同期通信まわりまとめ
【Nuxt.js】Nuxt文法編:非同期通信やasyncDataの使い方
参考:
ES2017でawaitのネストを避ける
【Nuxt.jsで近くのお店を探すアプリを作成】#4 async/await
awaitはPromiseで処理を止めるもの
ではまずawait
がそもそも何か❓
ようは処理を止めるものです💥✋await
の処理が終わるまでに
止めておきたい処理を
中に書けば良いということです✍️
await
の処理が終わるまで、
他の処理を停止させる
といった方が良いかもしれません。
.then
の場合は
「それが成功したら」の意味合いなので
日本語に置き換えた文法的に
しっくりきていました。
なので、
止めたい処理を書く
ということが最初は
中々理解できませんでした。。。
簡単に理解したいから
日本語に置き換える…
これはやめた方が良いですね。
コード例①
⬇️簡単なコードはこちら
前置きと同じコードです。
await
が終わってからの処理を
その下に書いていきます。
この場合はfirebaseAuthの
アカウント作成が完了してからdispatch('checkLogin')
1 2 3 4 5 6 7 8 9 10 11 12 13 |
export const actions = { async register({ dispatch }, payload) { try { await this.$fire.auth.createUserWithEmailAndPassword( payload.email, payload.password ) dispatch('checkLogin') } catch (error) { console.log(error) //eslint-disable-line } }, } |
コード例②
await
の後ろの.then
が省けます。
before
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
export const actions = { async login({ dispatch }, payload) { try { await this.$fire.auth .signInWithEmailAndPassword(payload.email, payload.password) .then(() => { dispatch('checkLogin') this.$router.push('/') }) .catch() } catch (error) { console.log(error) //eslint-disable-line } }, |
after
1 2 3 4 5 6 7 8 9 10 11 12 13 |
export const actions = { async login({ dispatch }, payload) { try { await this.$fire.auth.signInWithEmailAndPassword( payload.email, payload.password ) dispatch('checkLogin') this.$router.push('/') } catch (error) { console.log(error) //eslint-disable-line } }, |
awaitのネストか.thenが必要な時とは
では今回の2つのパターンに
当てはまるコードは
どんな場合だと思いますか❓
こちらのコードを見てください👀
firebaseのStorageにput
が成功してからgetDownloadURL
したい(★部分)
このまま書いてしまうと、
オブジェクトがないというエラーです💥
これはStorageの公式コードにも.then
が使われています。
Download Data via URL
Promise
の使用が必要です。
つまり今回の2つのパターンに当てはまります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
export const actions = { async register({ dispatch, state }, payload) { try { await this.$fire.auth.createUserWithEmailAndPassword( payload.email, payload.password ) dispatch('checkLogin') const storageRef = this.$fire.storage.ref() ★storageRef.child(`users/${state.user.uid}.png`).put(payload.thumbnail) ★storageRef.child(`users/${state.user.uid}.png`).getDownloadURL() } catch (error) { console.log(error) //eslint-disable-line } }, } |
Aの処理をしてからBの処理をしたい
ではawait
内で、
更にawait
したい場合はどうなるのか。
BでAの値を取得してから処理をしたい❗️
Aの処理を先にしてからBの処理をしたい❗️
って場合ですね🍀
おさらいですが、
この2つのパターンを使用します。
・await
でawait
をネスト
・await
で.then
のメソッドチェーン
await
は.then
の代わりなので、
個人的にはせっかくならawait
で揃えた方が良いなぁ🎈🧸
と思いますが、await
のネストが嫌😖💦
という方もいるので、
お好み&チームに合わせて
どちらもできるとGood⭕️
まぁawait
に限らずですが。
awaitのネスト
単純にawaitのネストをすればOK。
関数を分ける場合に有効。async A() { await hogehoge }
async B() { await (await A()) hogehoge }
firebase関連でできるコードサンプル
探し中です🔍
.thenでメソッドチェーン
awaitの処理が終わってから
やりたい処理を.then以降に記載✍️
async A() { await hogehoge.then(() => { hogehoge })}
処理によってはawaitのネスト不可
目次「awaitはPromiseで処理を止めるもの」内
「awaitのネストか.thenが必要な時とは」
で出したAuthとStorageを
使用したコードが良い例です💡
register
してupdateProfile
したい場合await dispatch
をしてもうまくいきません。update
でurl
が見当たらなくなってしまいます。
error 'url' is not defined
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
export const actions = { async register({ dispatch, state }, payload) { try { const res = await this.$fire.auth.createUserWithEmailAndPassword( payload.email, payload.password ) dispatch('checkLogin') const storageRef = this.$fire.storage.ref() storageRef.child(`users/${state.user.uid}.png`).put(payload.thumbnail) await dispatch('update', payload) return res } catch (error) { console.log(error) //eslint-disable-line } }, async update(payload) { const storageRef = this.$fire.storage.ref() await storageRef.child(`users/${state.user.uid}.png`).getDownloadURL() this.$fire.auth.currentUser.updateProfile({ displayName: payload.name, photoURL: url, }) this.$router.push('/register/finish') return url }, } |
update
をregister
内でしか
使わない前提の場合は
分ける必要がないのですが。
そして公式コード的にも.then
が良さそうです。
Download Data via URL
なのでこの場合はawait
の後に.then
で繋げる
メソッドチェーンを使用🍒
正しいコードはこちら👇
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
export const actions = { async register({ dispatch, state }, payload) { try { await this.$fire.auth.createUserWithEmailAndPassword( payload.email, payload.password ) dispatch('checkLogin') const storageRef = this.$fire.storage.ref() storageRef .child(`users/${state.user.uid}.png`) .put(payload.thumbnail) .then(() => { storageRef .child(`users/${state.user.uid}.png`) .getDownloadURL() .then((url) => { this.$fire.auth.currentUser.updateProfile({ displayName: payload.name, photoURL: url, }) this.$router.push('/register/finish') }) }) } catch (error) { console.log(error) //eslint-disable-line } }, } |
まとめ
await
のモヤモヤが
スッキリしました✨await
のネストを使用したいのですが、
firebaseで試せるものが
まだ見当たらないため、
発見次第のせていきます🔍