【问题标题】:Promise then() on vuex action inside component在组件内部的 vuex 操作上承诺 then()
【发布时间】:2019-10-22 10:34:54
【问题描述】:

一般来说,我喜欢将 vuex 操作背后的大部分逻辑保留在我的模块中,这样我就可以保持组件干净,并且大部分逻辑都收集在模块中(这对我来说似乎是最佳选择),问题是有时我需要在动作完成后(通常涉及 axios 承诺)完成后在组件数据中执行一些动作(例如,在成功的 ajax 调用后清除表单),我想我通过在我的 vuex 动作调用中添加一个 then 闭包并返回 axios 来解决这个问题promise 在我的模块中,但我注意到 then 闭包将始终立即解决,而不是仅在一切正常时才解决,200 OK。

这是我的组件:

stripeSourceHandler: function(sourceId)
    {
        if(this.customerSources.length == 0)
        {
            console.log('createSourceAndCustomer');
            this.createSourceAndCustomer({ id: sourceId, paymentCity:this.paymentCity, paymentAddress:this.paymentAddress })
            .then(() => {
                this.clearForm();
            });
        }
}

我的 vuex 模块操作:

createSourceAndCustomer({ commit }, sourceData)
    {
        commit('Loader/SET_LOADER', { status:1, message: 'Añadiendo forma de pago...' }, { root: true });
        return axios.post('/stripe/create-source-and-customer', sourceData)
        .then((response) => {
            commit('Loader/SET_LOADER', { status:2, message: response.data.message }, { root: true });
            commit('CREATE_SOURCE_AND_CUSTOMER', response.data.customer);
        }, 
        (error) => {
            commit('Loader/SET_LOADER', { status:3, errors: error, message: 'Oops, algo salio mal..' }, { root: true });
        });
    },

总而言之,我希望 clearForm 方法仅在 axios 调用成功时才发生,而不是总是触发。

【问题讨论】:

  • 在您的代码中没有明显的原因应该在帖子返回之前返回 Promise。为了确保,暂时用新的Promise(resolve => { setTimeout(() => resolve()), 1e4}) 替换您的方法内容。如果它立即返回,我们在您的控制器中遗漏了一些东西,并且它不包含在问题中。 minimal reproducible example 肯定会有所帮助。如果它按预期工作,那么您的 axios(或特定呼叫)有问题。

标签: javascript php laravel vue.js


【解决方案1】:

您返回 axios 帖子,但也从中链接,如果您想这样做,那么我建议使用 async/await 模式来清理代码并避免嵌套的承诺链接。这是重构后的样子:

async createSourceAndCustomer({ commit }, sourceData){
  try {
    commit('Loader/SET_LOADER', { status:1, message: 'Añadiendo forma de pago...' }, { root: true });
    const { data : { message } } = await axios.post('/stripe/create-source-and-customer', sourceData)
    commit('Loader/SET_LOADER', { status:2, message }, { root: true });

    return Promise.resolve()

  } catch (err) {
    commit('Loader/SET_LOADER', { status:3, errors: error, message: 'Oops, algo salio mal..' }, { root: true });

    return Promise.reject()
  }           
},

对你来说更干净一点,它会解决你的问题。

编辑

如果您不想使用这种模式,那么您可以将代码包装在一个新的 Promise 中,如下所示:

createSourceAndCustomer({ commit }, sourceData)
    {
      return new Promise ((resolve, reject) => {
        commit('Loader/SET_LOADER', { status:1, message: 'Añadiendo forma de pago...' }, { root: true });
        axios.post('/stripe/create-source-and-customer', sourceData)
        .then((response) => {
            commit('Loader/SET_LOADER', { status:2, message: response.data.message }, { root: true });
            commit('CREATE_SOURCE_AND_CUSTOMER', response.data.customer);
            resolve()
        }, 
        (error) => {
            commit('Loader/SET_LOADER', { status:3, errors: error, message: 'Oops, algo salio mal..' }, { root: true });
            reject()
        });
      })
    },

【讨论】:

  • 抱歉新手问题,但我将如何在我的组件中处理以从那里触发 clearFrorm,我会使用 then() 相同的权利吗?您能否也解释一下这个嵌套链接问题并提供一些示例,您的代码看起来既漂亮又干净,我也认为在我的代码中开始使用 try catch 块会有所帮助。
  • @gabogabans 用非 try/catch async/await 方法更新了我的问题。此外,关于您的其余代码不会改变
猜你喜欢
  • 2019-07-30
  • 2020-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-27
  • 2021-02-02
  • 1970-01-01
  • 2018-04-24
相关资源
最近更新 更多