【问题标题】:Promise-like Axios request in Vue componentVue 组件中类似 Promise 的 Axios 请求
【发布时间】:2021-05-06 19:39:02
【问题描述】:

我想以 Promise 风格的方式发出 Axios 请求。 Axios 请求在“dataLayer.js”中完成。 问题是我的“dataPromise”已经满了。 如何在数据层类中扩展“createChargingStations()”以进行类似 Promise 的调用,以便可以使用“.then()”处理 SFC 中的数据,如下所示?

非常感谢!

// dataLayer.js
export class modelFactory {  
    chargingStationsArray = []

    createChargingStations() {
        const requestPromise = axios.request(/* some request config */)
        const dataPromise = requestPromise.then(response => {
            response.data.forEach(dataEntry => {
                let cs = new chargingStation()
                /* some data mapping and transformation here */
                /* ... */
                
                // after tranformation, finally push chargingStation object
                this.chargingStationsArray.push(cs)
            })
        }).catch(error => {
            console.log("Promise Rejected: " + error);
        })
    }
}

// SFC.vue
<template> <!-- some template --> </template>

<script>
export default {
    /* name, components, data() etc. */
    methods: {
        updateMapOnFilterChange() {
            var mf = new modelFactory()
            const promise = mf.createChargingStations()
            
            promise.then(chargingStationsArray => {
                /* inject array into Vue component property */
            }).catch(error => {
               console.log("Promise Rejected: " + error);
            })
        }
    }
}
</script>

编辑:在这里发布了代码的长版本https://jsfiddle.net/3azdnc4j/ 您可能会更好地掌握代码应该做什么。但在我看来,基本问题没有必要!

【问题讨论】:

  • 不知道你已经改变了什么。您可以只链接承诺,并且不要忘记在函数中返回它。有时这是一个艰难的概念。
  • 您的代码不应该按原样工作,promise.then() 应该抛出。请创建一个minimal reproducible example 像codesanbox
  • 不确定,你想实现什么,你想访问你的 vue 文件中的chargingStationsArray 数据吗?
  • @Naren: 是的,我想在 vue 组件中访问完整的chargingStationsArray,然后请求就完成了
  • @TJ:我试过了,但是 babel 转译和正确的 vue 版本有问题。所以我决定以一种抽象和孤立的方式提出我的问题,因为这更像是一个概念问题。

标签: javascript vue.js axios es6-promise


【解决方案1】:

dataLayer 服务导出ModelFactory,返回axios 承诺,在mapped 响应内createChargingStations

// dataLayer.js
class ModelFactory {  

    createChargingStations() {
        return axios.request(/* some request config */).then(response => {
            const chargingStationsArray = response.data.map(dataEntry => {
                let cs = new chargingStation()
                /* some data mapping and transformation here */
                /* ... */
                
                // after tranformation, finally push chargingStation object
                return cs
            })
            return chargingStationsArray
        }).catch(error => {
            console.log("Promise Rejected: " + error);
            throw new Error('some error')
        })
    }
}

export default new ModelFactory()

并导入vue文件。

// SFC.vue
<template> <!-- some template --> </template>

<script>
import modelFactoryInstance from 'path-to-file/dataLayer'

export default {
    /* name, components, data() etc. */
    methods: {
        updateMapOnFilterChange() {
            modelFactoryInstance.createChargingStations().then(chargingStationsArray => {
            console.log(chargingStationsArray)
                /* inject array into Vue component property */
            }).catch(error => {
               console.log("Promise Rejected: " + error);
            })
        }
    }
}
</script>

【讨论】:

    【解决方案2】:

    代码将在const promise = mf.createChargingStations() 失败,因为createChargingStations 没有返回承诺。

    应该在使用 promise 时处理错误,在 createChargingStations 内处理它会使其通过 undefined 解决。

    promise 无法与 chargingStationsArray 解析。

    应该是:

    createChargingStations() {
        const requestPromise = axios.request(/* some request config */)
        const dataPromise = requestPromise.then(response => {
            ...
        });
        return dataPromise;
    }
    

    updateMapOnFilterChange() {
        var mf = new modelFactory()
        const promise = mf.createChargingStations()
        
        promise.then(() => {
            mf.chargingStationsArray.forEach(...)
        }).catch(error => {
           console.log("Promise Rejected: " + error);
        })
    }
    

    createChargingStationsupdateMapOnFilterChange 都可以用async..await 以简化的方式重写。

    【讨论】:

    • 它应该是一个独立的数据层。所以我不想在 Vue 组件中运行数据转换
    • 什么样的数据转换?你可以做await mf.createChargingStations(); this.chargingStationsArray = mf.chargingStationsArray。 ChargeStationsArray 被处理到不需要转换的地步。
    • 不,他们说不要使用 async/await。如果你没有完全掌握承诺。代码只是生成了一些模型对象,但是我如何在 Vue 组件中以我在代码中显示的方式使用这些对象
    • 我同意承诺。这里 async/await 是原始 Promise 的直接对应物,你可以随意使用你想要的。一旦mf.chargingStationsArray 被填充,就可以通过将其分配给this 在组件中使用它。这个问题并没有很好地说明问题到底是什么。至于代码问题,它们在答案中进行了解释。问题是如何使用then 的数据,就是这样,如果没有指定的修复程序,它将无法正常工作。
    猜你喜欢
    • 2020-02-14
    • 2022-01-01
    • 2020-06-13
    • 2019-04-20
    • 1970-01-01
    • 2020-01-03
    • 1970-01-01
    • 2020-07-16
    • 1970-01-01
    相关资源
    最近更新 更多