반응형
Vuejs 비동기 데이터 함수의 중첩된 약속
최소한으로 줄이자.
여기 서버에서 데이터를 가져오는 작은 컴포넌트가 있습니다.이 컴포넌트와 다른 컴포넌트의 차이점은 2개의 AJAX 콜을 실행해야 한다는 것입니다.줄줄이!
<template>
<div>Easy</div>
</template>
<script>
import axios from 'axios'
let firstFetch = () => {
return axios.get('/first')
}
let secondFetch = () => {
return axios.get('/second')
}
export default {
name: 'p-components-accordion-box',
methods: {
setActive(index) {
this.$emit('setActive', index)
}
},
asyncData({store, route, router}) {
return new Promise((resolve, reject) => {
firstFetch()
.then((result) => {
secondFetch()
.then((result) => {
resolve()
})
.catch((error) => {
throw { url: '/404' };
})
})
.catch((error) => {
throw { url: '/404' };
})
})
}
}
</script>
<style>
</style>
문제는 이 작업이 완벽하다는 것입니다. 모든 요청 작업이 완료됩니다.하지만 만약 일이 잘못되면 내가 할 수 있어
throw { url: '/404' };
브라우저에서는 완벽하게 작동합니다. 즉, '/404'로 이동하지만 NodeJS에서는 이 메시지가 계속 표시됩니다.
처리되지 않은 약속거부 경고:처리되지 않은 약속 거부.이 에러는, 캐치 블록이 없는 비동기 함수의 내부에 송출하거나, 또는 .catch()로 처리되지 않은 약속을 거부함으로써 발생합니다(거부 ID: 1).
비슷한 일을 해본 사람이 있나요?
에러를 내부에 넣는 대신asyncData
, 약속을 거부합니다.
export default {
name: 'p-components-accordion-box',
methods: {
setActive(index) {
this.$emit('setActive', index)
}
},
asyncData({store, route, router}) {
return new Promise((resolve, reject) => {
firstFetch()
.then((result) => {
secondFetch()
.then((result) => {
resolve()
})
.catch((error) => {
reject()
})
})
.catch((error) => {
reject()
})
})
}
}
그런 다음 이 방법을 사용할 때마다 오류를 포착하여 처리할 수 있습니다.
this.asyncData(.....)
.then(.....)
.catch(error => {
throw { url: '/404' }
})
결국 이것은 잘 될 것 같다.이것은 상용판이 아니라 최종 코드입니다.
Component.vue - 비동기 데이터()
asyncData({store, route, router}) {
let data = {
ca: route.params.ca,
province: route.params.province,
locality: route.params.locality,
}
return store.dispatch('FETCH_MAP_COORDINATES_AND_PROPERTIES', data)
.catch(() => {
if (process.browser) {
router.push('/404')
}else{
console.log("beforeThrow1");
throw { url: '/404' };
}
})
}
이것은 FETCH_MAP_COORDINATES_입니다.AND_PROPERTIES 액션
let FETCH_MAP_COORDINATES_AND_PROPERTIES = ({commit, dispatch, state}, data) => {
return new Promise((resolve, reject) => {
fetchMapCoordinatesV2(data, state.axios)
.then((result) => {
if (result.status !== 200) {
logger.error({
key: 'src.api.map.fetchMapCoordinates.then.badResponse',
data: result.data
})
reject(result)
}
logger.info({
key: 'src.api.map.fetchMapCoordinates.then',
})
result = result.data
let center = {
lat: result.location.data.geocode.data.lat,
lon: result.location.data.geocode.data.lon
}
let zoom = result.location.data.zoom
commit('SET_PROPERTY_MAP_CENTER', result.location.data.geocode.data )
commit('SET_PROPERTY_MAP_BOUNDS', result.location.data.geocode )
let default_coords = {
ne: {
lat: result.location.data.geocode.data.ne_lat,
lon: result.location.data.geocode.data.ne_lon,
},
nw: {
lat: result.location.data.geocode.data.nw_lat,
lon: result.location.data.geocode.data.nw_lon,
},
se: {
lat: result.location.data.geocode.data.se_lat,
lon: result.location.data.geocode.data.se_lon,
},
sw: {
lat: result.location.data.geocode.data.sw_lat,
lon: result.location.data.geocode.data.sw_lon,
}
}
fetchMapProperties(default_coords, state.axios)
.then((result) => {
logger.info({
key: 'store.actions.map.index.FETCH_MAP_PROPERTIES.then',
data: result.data
})
commit('SET_MAP_PROPERTIES', result.data)
resolve(result.data)
})
.catch((error) => {
logger.error({
key: 'src.api.map.fetchMapProperties.catch',
coords: default_coords,
data: error
})
reject(error)
})
})
.catch((error) => {
logger.error({
key: 'src.api.map.fetchMapCoordinatesV2.catch',
data: error
})
reject(error)
})
})
};
다음 두 가지 가져오기 방법이 있습니다.
let fetchMapCoordinatesV2 = (data, axios) => {
let query = '';
if (data.ca) query = query + `/${data.ca}`
if (data.province) query = query + `/${data.province}`
if (data.locality) query = query + `/${data.locality}`
logger.info({
key: 'fetchMapCoordinatesV2',
query: query
})
return axios.get(`/locations${query}`)
}
let fetchMapProperties = (coords, axios) => {
return new Promise((resolve, reject) => {
axios.post(`/properties/map`, coords)
.then((result) => {
logger.info({
key: 'src.api.map.fetchMapProperties.then',
coords: coords
})
resolve(result)
})
.catch((error) => {
logger.error({
key: 'src.api.map.fetchMapProperties.catch',
coords: coords,
data: error.response
})
reject(error)
})
});
}
현재 동작하고 있습니다.두 콜이 모두 성공했을 경우 올바르게 렌더링되며, http 콜 중 하나가 실패하거나 200 이외의 상태 코드를 수신했을 경우 /404가 렌더링됩니다.
언급URL : https://stackoverflow.com/questions/50396629/nested-promise-in-vuejs-asyncdata-function
반응형
'programing' 카테고리의 다른 글
스타일 바인딩을 @click - vue.syslog로 지정합니다. (0) | 2022.09.01 |
---|---|
탈퇴 전환이 활성화되어 있는 동안 구성 요소 렌더링 계속 (0) | 2022.09.01 |
wait()가 항상 동기화된 블록에 있어야 하는 이유 (0) | 2022.09.01 |
InputStream에서 File 객체를 생성할 수 있습니까? (0) | 2022.09.01 |
C의 파일 설명자에서 파일 이름 검색 (0) | 2022.09.01 |