Vue Actions中的菊花链承诺导致无限循环

时间:2017-09-01 11:35:25

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

我有一个关于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变异,这很奇怪,如果我解决它不应该只是结束吗?

EXTRA ::

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

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

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

这可能是问题的原因吗?

1 个答案:

答案 0 :(得分:0)

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

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

希望这有助于将来。