비동기적이고 순차적으로 Vuex 작업 실행 - 이해가 안 되는 부분은 무엇입니까?
Vuex 스토어가 있는데 Firebase Realtime Database에서 데이터를 가져오려고 합니다.처음에는 사용자 정보를 가져오고 있지만, 나중에 가져온 초기 데이터에 따라 다른 정보를 가져오고 싶습니다.
수를 사용하여 이 만, 이 두마다 / 대기가 실행됩니다.created()
후크, 사용자 정보가 초기화되지 않기 때문에 두 번째 작업이 실패합니다.
내 사용자 스토어
async fetchCreds({ commit }) {
try {
firebase.auth().onAuthStateChanged(async function(user) {
const { uid } = user
const userDoc = await users.doc(uid).get()
return commit('SET_USER', userDoc.data())
})
} catch (error) {
console.log(error)
commit('SET_USER', {})
}
}
위의 호출에 의존하는 나의 클럽 액션
async fetchClubInformation({ commit, rootState }) {
try {
const clubIDForLoggedInUser = rootState.user.clubId
const clubDoc = await clubs.doc(clubIDForLoggedInUser).get()
return commit('SET_CLUB_INFO', clubDoc.data())
} catch (error) {
console.log(error)
}
}
}
my component의 created() 메서드 내에서 호출되는 메서드.
created: async function() {
await this.fetchCreds();
await this.fetchClubInformation();
this.loading = false;
}
근본적으로 비동기/대기라고 오해하고 있는 것 같습니다만, 코드에 무엇이 잘못되어 있는지 이해할 수 없습니다.도와주시면 감사하겠습니다.
저는 Firebase에 대해 잘 모르지만 소스코드를 좀 더 자세히 살펴본 후에 당신의 문제를 조금 밝혀줄 수 있을 것 같습니다.
우선, 다음의 예를 검토해 주세요.
async function myFn (obj) {
obj.method(function () {
console.log('here 1')
})
console.log('here 2')
}
await myFn(x)
console.log('here 3')
질문:.로그 메시지는 어떤 순서로 표시됩니까?
, ②.here 2
올 것이다here 3
위의 로는 언제인지 알 수here 1
무엇이냐에 따라 obj.method
전달된 함수와 관련이 있습니다.수 있습니다를 들어 Array's の ((((((((((((((((((().forEach
method이 경우 method)는here 1
이랬다콜 는, 「」( 「」, 「」)입니다.here 1
않을 도 있다here 3
.
async
수식자는 Promise 자체를 반환하지 않는 경우 함수의 Promise를 암묵적으로 반환합니다.해당 Promise의 해결된 값은 함수에서 반환된 값이 되며 Promise는 함수가 반환되는 시점에서 해결됩니다.를 사용하지 않는 함수의 경우return
에는 '이렇게 하다'로return undefined
.
따라서 키 포인트를 강조하기 위해 비동기 함수에 의해 반환되는 Promise는 해당 함수가 반환될 때까지 대기할 뿐입니다.
법onAuthStateChanged
는 비동기적으로 콜백을 호출하기 때문에 그 콜백 내의 코드는 주변 함수가 완료될 때까지 실행되지 않습니다.암묵적으로 반환된 Promise에는 콜백이 호출될 때까지 기다리도록 지시할 필요가 없습니다.await
이 함수는 아직 호출되지 않았기 때문에 콜백 내부는 관련이 없습니다.
Promise를 에 통상 은 Firebase Promise에 .return
★★★★★★★★★★★★★★★★★」await
련련: :
// Note: This WON'T work, explanation follows
return firebase.auth().onAuthStateChanged(async function(user) {
// Note: This WON'T work, explanation follows
await firebase.auth().onAuthStateChanged(async function(user) {
하지 않습니다.왜냐하면 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」onAuthStateChanged
는 실제로 Promise를 한다.그것은 약속을 반환한다.unsubscribe
★★★★★★ 。
약속하다단, 다음을 사용하여 새로운 약속 작성new Promise
이치노일반적으로 Promise를 제대로 지원하지 않는 코드를 래핑할 때만 필요합니다.적절한 Promise 지원을 제공하는 라이브러리로 작업하는 경우 Promise를 만들 필요가 없습니다.
왜 안 거죠?onAuthStateChanged
속을을? 츠요시
모든 사인/사인아웃 이벤트를 시청하는 방법이기 때문입니다.사용자가 로그인 또는 로그아웃할 때마다 콜백이 호출됩니다.특정 사인인을 보기 위한 방법은 아닙니다.약속은 단일 값으로 한 번만 해결할 수 있습니다.따라서 단일 사인 이벤트를 Promise로 모델링할 수 있지만 모든 사인/사인아웃 이벤트를 시청하는 것은 의미가 없습니다.
★★★★★★★★★★★★★★★★★.fetchCreds
는 모든 사인/사인아웃이벤트를 통지받기 위해 등록하고 있습니다.돌아온 사람하고는 아무 상관이 없어요.unsubscribe
따라서 페이지가 새로고침될 때까지 이러한 모든 이벤트를 듣습니다.「 」에 fetchCreds
몇 번이고 더 많은 청취자가 추가될 것이다.
사용자의 로그인이 완료되기를 기다리는 경우 대신 직접 기다리는 것이 좋습니다. firebase.auth()
에는 접두사로 가 있습니다.signIn
예 , ) 。signInWithEmailAndPassword
사용자의 로그인이 완료되면 해결되는 Promise가 반환됩니다.해결된 값은 사용자를 포함한 다양한 정보에 대한 액세스를 제공합니다.어떤 방법을 사용하시는지는 모르겠지만 아이디어는 거의 동일합니다.
다만, 현재의 유저의 상세를 파악하는 것에 정말로 관심이 있는 것일 수도 있습니다.안 돼요.onAuthStateChanged
조금도.복사만 하면 됩니다.currentUser
거 요.다음과 같이 합니다.
async fetchCreds({ commit }) {
try {
const { uid } = firebase.auth().currentUser
const userDoc = await users.doc(uid).get()
commit('SET_USER', userDoc.data())
} catch (error) {
console.log(error)
commit('SET_USER', {})
}
}
이미 언급했듯이, 이것은 사용자가 이미 로그인하고 있다는 가정에 의존합니다.안전한 가정이 아닌 경우 사용자 자격 증명이 필요한 구성 요소를 만들기 전에 로그인이 완료될 때까지 기다리는 것이 좋습니다.
업데이트:
코멘트로부터의 질문:
obj.method() 콜이 비동기이며 콜백 함수를 대기하고 있는 경우, 내부 비동기 함수(myFn)가 종료할 때까지 외부 비동기 함수(myFn)가 해결되지 않는 것을 확인할 수 있습니까?
무슨 말씀을 하시는지 잘 모르겠습니다.
말씀드리면, 저는 단어 .async
및 비동기입니다.다음과 같은 기능setTimeout
비동기라고 생각되지만 그렇지 않습니다.async
.
async
/await
이 많이 뿐입니다Promise'는것이 Promise를 입니다.실제로 기능을 기다리는 것이 아니라 약속을 기다리는 것입니다.요.async
약속하다
따라서 콜백 기능을 기다리라고 하는 것은 그 의미가 명확하지 않습니다.어떤 약속을 원하십니까?await
넣다async
함수의 수식어는 마법처럼 무언가를 기다리게 하지 않습니다.은 단지 마주칠 때만 기다린다.await
다른 비동기 콜은 계속 사용할 수 있습니다.async
통상의 함수와 같이, 이러한 콜은 함수가 복귀한 후에 실행됩니다.는 '일시정지'밖에 요.await
★★★★★★ 。
「 」를 .await
다른 함수(네스트된 함수라도 외부 함수가 내부 함수를 대기하고 있지 않는 한 외부 함수가 내부 함수를 대기하는지 여부에 아무런 차이가 없습니다. '약속'이 있다.then
await
것을 더하는 then
약속에 호소합니다. 이 않는 한수 없습니다.async
고장나려면 됩니다.체인이 고장나려면 링크가 하나만 있으면 됩니다.
이전 예를 수정하면 다음과 같습니다.
async function myFn (obj) {
await obj.method(async function () {
await somePromise
// ...
})
// ...
}
await myFn(x)
3가지 . 즉, 3가지 기능이 있습니다.myFn
,method
되었습니다.method
「Will 」입니다await myFn(x)
somePromise
위의 코드로는 알 수 없습니다.은 어떤 .method
내부적으로는 합니다.를 들어, 「」의 ,method
이렇게 생겼지만 여전히 작동하지 않습니다.
function method (callback) {
setTimeout(callback, 1000)
}
「 」를 .async
method
도움이 안 돼요. 그러면 프로미스가 돌아오지만 프로미스는 타이머가 켜질 때까지 기다리지 않을 거예요.
약속해 주세요. myFn
둘 다 , '콜백'이 아닌 한method
이 약속들을 함께 연결하면 효과가 없을 것입니다.
「」의 는, 「」입니다.method
되어 있습니다. 타깃 수 .이것에 의해, 타겟의 동작이 개시됩니다.
function method (callback) {
return someServerCallThatReturnsAPromise().then(callback)
}
우리가 사용할 수 있었을텐데async
/await
대신 여기에서는 약속을 직접 돌려드릴 수 있기 때문에 그럴 필요가 없었습니다.
또한 비동기 myFn 함수에서 아무것도 반환하지 않으면 즉시 정의되지 않은 상태로 해결됩니까?
여기서 당장라는 용어는 잘 정의되지 않는다.
- 하지 않는 「반환」을 가지는 .
return undefined
마지막에. - 에 의해 반환된 약속
async
함수는 함수가 반환되는 지점에서 해결됩니다. - Promise에 대해 해결된 값은 반환된 값입니다.
'돌아가다'로 이 됩니다.undefined
까지 해결은 않습니다 기능이 종료될 때까지 해결은 이루어지지 않습니다.「」가 되어 있지 않은 .await
이 경우 동기 함수가 '일시적으로' 반환되는 것과 같은 의미로 '일시적으로' 발생합니다.
★★★★★★★★★★★★★★.await
then
및 ", "then
콜은 항상 비동기입니다.그래서 이 약속이 '즉시' 해결되겠지만await
그에 다른 .매우 짧은 대기 시간이지만 동기화가 되지 않으므로 그 사이에 다른 코드를 실행할 수 있습니다.
다음 사항을 고려하십시오.
const myFn = async function () {
console.log('here 3')
}
console.log('here 1')
Promise.resolve('hi').then(() => {
console.log('here 4')
})
console.log('here 2')
await myFn()
console.log('here 5')
로그 메시지는 번호가 매겨진 순서대로 표시됩니다. ★★★★★★★★★★★★★★★★★★★★★myFn
'하면 '빨리'가 here 4
here 3
★★★★★★★★★★★★★★★★★」here 5
.
간단히 말하면
fetchCreds({ commit }) {
return new Promise((resolve, reject) => {
try {
firebase.auth().onAuthStateChanged(async function(user) {
const { uid } = user
const userDoc = await users.doc(uid).get()
commit('SET_USER', userDoc.data())
resolve()
})
} catch (error) {
console.log(error)
commit('SET_USER', {})
resolve()
}}
}
async () => undefined // returns Promise<undefined> -> undefined resolves immediatly
asnyc () => func(cb) // returns Promise<any> resolves before callback got called
() => new Promise(resolve => func(() => resolve())) // resolves after callback got called
언급URL : https://stackoverflow.com/questions/56878908/firing-vuex-actions-asynchronously-and-sequentially-what-am-i-not-understandin
'source' 카테고리의 다른 글
오류: Java: 잘못된 대상 릴리스: 11 - IntelliJ IDEA (0) | 2022.07.17 |
---|---|
자바에서는 언제 varargs를 사용합니까? (0) | 2022.07.17 |
포인터를 사용하는 이유 (0) | 2022.07.17 |
vuetify에서 vuelidate 검증 관리 (0) | 2022.07.17 |
vue - 최신 하위 경로 제거 (0) | 2022.07.17 |