【问题标题】:Daisy-chaining promises in Vue Actions results in infinite loopVue Actions 中的菊花链承诺导致无限循环
【发布时间】:2017-09-01 11:35:25
【问题描述】:

我有一个关于 VueJS 设置中的 Javascript Promises 的问题,我有一个应用程序使用 Action 从 IndexedDB(如果已设置)或通过发出 Axios HTTP 请求从 API 获取国家列表。

现在,我正在从操作中返回一个承诺,因为我希望能够在此任务完成时触发 UI 中的一些弹出窗口,并且除此之外,Axios 和 Dexie(我用于 IndexedDB)都运行通过 Promises 本身异步进行。

  getCountries({commit, dispatch}) {

    commit(types.MUTATIONS.SET_LOADING, true, {root: true})
    commit(types.MUTATIONS.SET_LOADER_MESSAGE, "Loading Countries Data...", {root: true})

    return new Promise((resolve, reject) => {
      db.countries.count().then(value => {
        if(value > 0) {
          console.log("Loading Countries from IndexedDB")
          db.countries.toArray().then(collection => {
            commit(types.MUTATIONS.COUNTRIES.SET, collection, {root: true})
            resolve(collection);
          })
        } else {
          fetchCountriesData().then(data => {
            console.log("Loading Countries from API Call")
            commit(types.MUTATIONS.COUNTRIES.SET, data, {root: true})
            db.countries.bulkAdd(data)
            resolve(data)
          }).catch(error => {
            reject(error)
          })
        }
      })
    })
  }

那是动作的代码,它只是按照我上面描述的那样做,问题是这会导致无限循环,LOADER 突变被一遍又一遍地触发。

究竟为什么会这样?谁能帮我理解这一点?似乎它运行了初始 API 操作,但是 THEN 之后,在国家已经加载的情况下,它会循环并再次运行,这次也调用 indexeddb 突变,这很奇怪,如果我解决了它不应该就这样结束吗?

额外::

在我的应用程序中的视图中调用该操作,我在 created() 挂钩中调用它,以便确保国家列表始终加载到我的 Vuex 状态中。

created() {
  this.getAllCountries().then(response => {}).catch(error => {
    snackbar("Unable to load countries!", "error")
  }).then(() => {
    this.setLoadingStatus(false);
  })
}

在这种情况下,如果没问题,它什么也不做,但将来可能会改变,出现错误时它应该显示一个弹出窗口,通知用户无法加载数据,并且在任何一种情况下它都应该隐藏加载栏(也是通过Vuex处理的)

这可能是问题的原因吗?

【问题讨论】:

  • 你在哪里执行这个 getCountries 函数?你能告诉我们吗?
  • @GMaiolo 将使用该信息更新问题,只需几秒钟
  • @GMaiolo 用所要求的信息更新了问题,如果您需要其他信息,请告诉我。
  • created 钩子中的函数是getAllCountries,你能提供它的代码吗?你可能在某处有一个无限循环

标签: javascript ecmascript-6 vuejs2 es6-promise vuex


【解决方案1】:

没关系,我的代码中有一个逻辑错误,主要是为了防止任何人在加载时能够单击项目,我有条件地使用v-if="loading" 设置视图,以便在加载时仅显示加载程序 div,否则显示实际布局。

这种方法的问题是每次再次显示主视图时它都会重新触发created钩子,从而导致我的愚蠢循环。

希望这对将来的人有所帮助。

【讨论】:

    猜你喜欢
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    相关资源
    最近更新 更多