Vuejs2 Vuejs asyncData函数中的嵌套承诺

Vuejs2 Vuejs asyncData函数中的嵌套承诺,vuejs2,es6-promise,vuex,vue-ssr,Vuejs2,Es6 Promise,Vuex,Vue Ssr,让我们把它浓缩到最低限度 我这里有一个从服务器获取数据的小组件。这个组件和其他组件的不同之处在于它必须执行两个AJAX调用。一个接一个 <template> <div>Easy</div> </template> <script> import axios from 'axios' let firstFetch = () => { return axios.get('/first')

让我们把它浓缩到最低限度

我这里有一个从服务器获取数据的小组件。这个组件和其他组件的不同之处在于它必须执行两个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>
它在浏览器中工作得非常好,这意味着我会转到“/404”,但在NodeJS上我会不断收到这条消息

未处理的PromisejectionWarning:未处理的承诺拒绝。这 错误源于异步函数的内部抛出 没有拦截,或拒绝未处理的承诺 with.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()

这是我的FETCH\u MAP\u坐标和属性操作

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。

好的,您可以在右侧的轨道上找到它。我正在添加我的最终解决方案。谢谢你的提示
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)
        })

    });

}