从Vuex操作返回承诺

承诺 Vue.js

伽罗卡卡西

2020-03-10

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

从概念上讲,Vuex对我来说是一种范式转换,但是我有信心我知道现在的全部情况,并且完全可以理解!但是存在一些小的灰色区域,主要是从实现的角度来看。

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

基本上,从动作中返回一个promise(类似)对象是否被视为一种好习惯?我将它们视为异步包装程序,带有失败状态等,因此看起来很适合返回承诺。相反,变异器只是改变事物,并且是商店/模块中的纯结构。

第412篇《从Vuex操作返回承诺》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

2个回答
2020.03.10

TL:DR; 仅在必要时从您的操作中返回承诺,但将相同的操作链接在一起。

很长时间以来,我还认为返回操作与单向数据流的Vuex周期相矛盾。

但是,也有边缘情况,其中从你的行动返回一个承诺可能是“必要的”。

想象一下一种情况,可以从2个不同的组件触发一个动作,并且每个组件以不同的方式处理故障情况。在这种情况下,需要将调用者组件作为参数传递,以在存储中设置不同的标志。

哑巴的例子

用户可以在导航栏和/ profile页面中编辑用户名的页面(包含导航栏)。两者都触发一个动作“更改用户名”,这是异步的。如果承诺失败,则该页面应仅在用户试图更改用户名的组件中显示错误。

当然,这是一个愚蠢的示例,但是我看不到一种方法,无需复制代码并通过2个不同的动作进行相同的调用即可解决此问题。

小胖Eva 2020.03.10

actions在Vuex中是异步的。让调用函数(动作的发起者)知道某个动作已完成的唯一方法是通过返回Promise并在以后解决它。

Here is an example: myAction returns a Promise, makes a http call and resolves or rejects the Promise later - all asynchronously

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);
            })
        })
    }
}

Now, when your Vue component initiates myAction, it will get this Promise object and can know whether it succeeded or not. Here is some sample code for the Vue component:

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")
        })
    }
}

As you can see above, it is highly beneficial for actions to return a Promise. Otherwise there is no way for the action initiator to know what is happening and when things are stable enough to show something on the user interface.

And a last note regarding mutators - as you rightly pointed out, they are synchronous. They change stuff in the state, and are usually called from actions. There is no need to mix Promises with mutators, as the actions handle that part.

Edit: My views on the Vuex cycle of uni-directional data flow:

If you access data like this.$store.state["your data key"] in your components, then the data flow is uni-directional.

The promise from action is only to let the component know that action is complete.

The component may either take data from promise resolve function in the above example (not uni-directional, therefore not recommended), or directly from $store.state["your data key"] which is unidirectional and follows the vuex data lifecycle.

The above paragraph assumes your mutator uses Vue.set(state, "your data key", http_data), once the http call is completed in your action.

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android