从 Vuex 操作返回 Promise

新手上路,请多包涵

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

从概念上讲,Vuex 对我来说是一种范式转变,但我相信我现在知道它的全部内容,并且完全理解它!但是存在一些小的灰色区域,主要是从实施的角度来看。

这个我觉得设计的不错,但是不知道是不是和Vuex单向数据流的 循环 相矛盾。

基本上,从一个动作中返回一个 promise(-like) 对象被认为是一种好的做法吗?我将它们视为异步包装器,具有失败状态等,因此似乎很适合返回承诺。相反,mutators 只是改变事物,并且是存储/模块中的纯结构。

原文由 Daniel Park 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
2 个回答

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

这是一个示例: myAction 返回一个 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);
            })
        })
    }
}

现在,当你的 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")
        })
    }
}

正如您在上面看到的,对于 actions 返回一个 Promise 非常有益。否则,动作发起者无法知道正在发生的事情以及事情何时足够稳定以在用户界面上显示某些内容。

最后一点关于 mutators 正如你正确指出的那样,它们是同步的。他们更改了 state 中的内容,并且通常从 actions 调用。无需将 Promisesmutators 混合,因为 actions 处理该部分。

编辑:我对单向数据流的 Vuex 循环的看法:

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

行动的承诺只是让组件知道行动已经完成。

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

上述段落假设您的 mutator 使用 Vue.set(state, "your data key", http_data) ,一旦在您的操作中完成了 http 调用。

原文由 Mani 发布,翻译遵循 CC BY-SA 3.0 许可协议

只是关于一个封闭主题的信息: 你不必创建一个承诺,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) => {
          commit('logUserIn', response.data);
        })
        .catch((error) => {
          commit('unAuthorisedUser', { error:error.response.data });
        })
    }

另一个例子:

     addEmployee({ commit, state }) {
      return insertEmployee(state.employee)
        .then(result => {
          commit('setEmployee', result.data);
          return result.data; // resolve
        })
        .catch(err => {
          throw err.response.data; // reject
        })
    }

另一个 异步等待的 例子

    async getUser({ commit }) {
        try {
            const currentUser = await axios.get('/user/current')
            commit('setUser', currentUser)
            return currentUser
        } catch (err) {
            commit('setUser', null)
            throw 'Unable to fetch current user'
        }
    },

原文由 Anoop Thiruonam 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题