从Vuex行动中回复承诺

Dan*_*ark 98 state-management promise vue.js es6-promise vuex

我最近开始将事物从jQ迁移到更结构化的框架VueJS,我喜欢它!

从概念上讲,Vuex对我来说已经是一个典型的转变,但我相信我现在知道它的全部内容,完全得到它!但是存在一些小的灰色区域,主要是从实施的角度来看.

我觉得这个设计很好,但不知道它是否与单向数据流的Vuex 周期相矛盾.

基本上,从动作中返回一个promise(类似)对象被认为是一种好习惯吗?我将它们视为异步包装器,具有失败状态等,因此似乎非常适合返回一个承诺.相反,mutators只是改变了一些东西,而且是商店/模块中的纯粹结构.

Man*_*ani 207

actions在Vuex中是异步的.允许调用函数(操作的发起者)知道操作完成的唯一方法是返回Promise并稍后解析它.

下面是一个示例:myAction返回a Promise,进行http调用并解析或拒绝Promise后者 - 全部异步

actions: {
    myAction(context, data) {
        return new Promise((resolve, reject) => {
            // Do something here... lets say, a http call using vue-resource
            this.$http("/api/something").then(response => {
                // http success, call the mutator and change something in state
                resolve(response);  // Let the calling function know that http is done. You may send some data back
            }, error => {
                // http failed, let the calling function know that action did not work out
                reject(error);
            })
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,当您的Vue组件启动时myAction,它将获取此Promise对象并可以知道它是否成功.以下是Vue组件的一些示例代码:

export default {
    mounted: function() {
        // This component just got created. Lets fetch some data here using an action
        this.$store.dispatch("myAction").then(response => {
            console.log("Got some data, now lets show something in this component")
        }, error => {
            console.error("Got nothing from server. Prompt user to check internet connection and try again")
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,actions返回a 非常有利Promise.否则,动作发起者无法知道发生了什么以及何时足够稳定以在用户界面上显示某些内容.

最后一点关于mutators- 正如你正确指出的那样,它们是同步的.他们改变了东西state,并且通常被称为actions.有没有必要混合Promises使用mutators,作为actions处理的一部分.

编辑:我对单向数据流的Vuex周期的看法:

如果您访问this.$store.state["your data key"]组件中的数据,则数据流是单向的.

行动的承诺只是让组件知道行动是完整的.

该组件可以从上面示例中的promise promise函数中获取数据(不是单向的,因此不推荐),或者直接从中获取$store.state["your data key"]单向的数据并遵循vuex数据生命周期.

Vue.set(state, "your data key", http_data)在您的操作中完成http调用后,上面的段落假定您的mutator使用.

  • “正如您在上面看到的,返回 Promise 的操作非常有益。否则,操作发起者无法知道正在发生的事情以及事情何时稳定到足以在用户界面上显示某些内容。” IMO,这缺少 Vuex 的重点。动作发起者不应该*需要*知道发生了什么。当数据从异步事件返回时,动作应该改变状态,并且组件应该根据 Vuex 存储的状态而不是 Promise 来响应该阶段的变化。 (8认同)
  • @ceejayoz 是正确的,您的商店当然可以用于提供有关操作何时完成的反馈,有时这是您应该做的。即触发一个动作并在完成(通过或失败)时提交突变。Vuex 是响应式的,因此可以很容易地观察状态。然而,Mani 的想法也是有效的,因为它提供了链接 Promise 的能力,这允许更清晰的工作流程,并且还可以在完成之前提交突变。因此,在 Promise 完成时,您知道状态是正确的,因为您已经调用了同步突变。 (5认同)
  • @DanielPark是的,"这取决于"场景和个人开发者偏好.在我的例子中,我想在我的状态中避免像`{isLoading:true}`这样的中间值,因此使用了Promises.您的偏好可能有所不同 在一天结束时,我们的目标是编写无杂乱且可维护的代码.无论承诺是实现了这个目标,还是vuex状态 - 都由个人开发者和团队来决定. (4认同)
  • @Mani 天哪,你是对的,在制作小提琴时想通了。非常感谢! (3认同)
  • @ceejayoz查看**撰写动作**(最后一节)在文档中 - http://vuex.vuejs.org/en/actions.html - 动作是异步的,因此返回Promise是一个好主意,如那些文档.也许不是在上面的$ http情况下,但在其他一些情况下,我们可能需要知道一个动作何时完成. (2认同)
  • @AmritKahlon 很高兴听到!我认为这是 [Rubber Duck Debugging](https://en.wikipedia.org/wiki/Rubber_duck_debugging) 通过 jsFiddle 和 stackoverflow 工作的完美示例。如果你有时间,请阅读它:-) (2认同)

Ano*_*P.A 27

只是关于一个封闭主题的信息: 你不必创建一个promise,axios返回一个:

参考:https://forum.vuejs.org/t/how-to-resolve-a-promise-object-in-a-vuex-action-and-redirect-to-another-route/18254/4

例:

export const loginForm = ({commit},data) => {
        return axios.post('http://localhost:8000/api/login',data).then((response) => {
            console.log(response);
            commit('logUserIn',response.data.data);
        }).catch((error) => {
            commit('unAuthorisedUser',{
                error:error.response.data
            })
        })
};
Run Code Online (Sandbox Code Playgroud)


Bha*_*idi 8

动作

ADD_PRODUCT : (context,product) => {
  return Axios.post(uri, product).then((response) => {
    if (response.status === 'success') {  
      context.commit('SET_PRODUCT',response.data.data)
    }
    return response.data
  });
});
Run Code Online (Sandbox Code Playgroud)

零件

this.$store.dispatch('ADD_PRODUCT',data).then((res) => {
  if (res.status === 'success') {
    // write your success actions here....
  } else {
     // write your error actions here...
  }
})
Run Code Online (Sandbox Code Playgroud)

  • 组件中未定义此无效响应 (3认同)
  • 我认为您忘记在 ADD_PRODUCT 函数中添加 return (2认同)