【问题标题】:Vuex: handle async action with promise call to REST APIVuex:通过对 REST API 的承诺调用来处理异步操作
【发布时间】:2018-09-25 17:53:25
【问题描述】:

我使用 TypeScript 和 Vue/Vuex 来创建一个玩具应用程序,我需要在渲染组件时从远程 API 加载项目列表。在以下操作中,我使用库 axios 发出 http 请求,并将其作为承诺返回:

const actions = {    
  getCurrentSession(context: Context) {
    return axios.get("http://localhost:3000/sessions/current")
      .then((res) => {
        commitSharedFiles(context, res.data.shared_files);
      })
      .catch((e: string) => {
        console.error(e);
      });
  }
};

// export action
export const dispatchGetSharedFiles = dispatch(actions.getCurrentSession);

// commit
export const commitSharedFiles = commit(mutations.setSharedFileList);

// mutations to the state tree
const mutations = {
  setSharedFileList(state: State, sharedFiles: StoreState.DirFile[]) {
    state.sharedFileList = sharedFiles;
  }
};

由于操作的异步特性,我必须在从存储/状态树中检索获取的文件列表之前解决承诺:

// this is called in the mounted() life cycle method:
Store.dispatchGetSharedFiles(this.$store).then(res => {
            this.sharedFiles = Store.readSharedFilesList(this.$store);
});

这可行,但我认为解决承诺然后获取数据非常复杂。有没有更好的方法在 Vuex 中使用异步操作?谢谢

【问题讨论】:

  • 看起来你已经实现了explicit promise construction anti-pattern。不要那样做
  • 感谢我刚刚删除了 Promise 包装器 :)
  • 在您的代码 sn-p 上下文中,commit 是什么? dispatch 也一样?整个commitSharedFiles 位没有多大意义。你把它当作一个函数来调用,但它似乎不是一个,除非commit(...) 以某种方式返回一个函数
  • commit 返回一个提交突变的函数,该突变指向指定的突变处理程序。 dispatch 调度动作到指定的动作处理程序。谢谢
  • 您能展示一下这些实现吗?没有他们,你的问题没有多大意义

标签: typescript asynchronous vue.js action vuex


【解决方案1】:

使用async/await 进行操作,使用映射的getter 从商店检索商品(也可以映射操作)。

// store.ts
const actions = {    
  async FetchSharedFiles(context: Context) {
    // omitted error handling for brevity
    let {res} = await axios.get("http://localhost:3000/sessions/current")
    commitSharedFiles(context, res.data.shared_files);
  }
};

// component.ts
import { mapGetters } from 'vuex'
...
mounted () {
  // again, do any necessary error handling
  this.$store.dispatch('FetchSharedFiles')
},
computed: {
  ...mapGetters({
    sharedFiles: 'namespace/getSharedFiles'
  })
}

使用此模式受益于 vuex 的反应性,因此组件中的 sharedFiles 将在操作完成并提交响应数据时触发更新。您的模板可能如下所示:

<template>
  <div v-for="(file, i) in sharedFiles" :key="i">
    // layout for each item...
  </div>
</template>

【讨论】:

    猜你喜欢
    • 2017-01-22
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    相关资源
    最近更新 更多