【问题标题】:Vue - Firebase commit action scoping issue?Vue - Firebase 提交操作范围问题?
【发布时间】:2018-09-29 09:10:27
【问题描述】:

我的这行代码不起作用:

actions: {
    getFirebaseDb({commit}) {
      let rooms = []
      db.collection("rooms").get().then(function(querySnapshot){
        querySnapshot.forEach(doc => {
            let room = doc.data()
            rooms.push(room)
        })
      })
      commit('SET_ROOMS', rooms)
    }
}

但后来有人告诉我将提交向上移动到 db.collection() 内部,如下所示:

actions: {
    getFirebaseDb({commit}) {
      let rooms = []
      db.collection("rooms").get().then(function(querySnapshot){
        querySnapshot.forEach(doc => {
            let room = doc.data()
            rooms.push(room)
        })
        commit('SET_ROOMS', rooms)
      })
    }
}

它有效。为什么?

我在 db.collection() 范围之外创建了 rooms 数组,因此它应该可以在外部提交。我不知道为什么会这样。想法?

【问题讨论】:

    标签: firebase firebase-realtime-database vue.js vuex


    【解决方案1】:

    因为作为.then() 的参数传递的函数是异步执行的。

    这意味着它不会立即执行,而是在(希望不久的)将来某个时间执行。

    这就是异步代码的方式,例如承诺,工作。 db.collection("rooms").get() 返回一个承诺。

    你的代码运行如下:

    getFirebaseDb({commit}) {
      let rooms = []                                              // this executes right away
      db.collection("rooms").get().then(function(querySnapshot){
        querySnapshot.forEach(doc => {                            // this executes in the future
            let room = doc.data()                                 // this executes in the future
            rooms.push(room)                                      // this executes in the future
        })                                                        // this executes in the future
      })
      commit('SET_ROOMS', rooms)                                  // this executes right away
    }
    

    让我们看一个描述这种情况的更简单的演示:

    let arr = [];
    console.log('right away 1', arr);
    
    setTimeout(function () {
      console.log('this will run 1 second later1', arr);
      arr.push('x');
      console.log('this will run 1 second later2', arr);
    }, 1000);
    
    console.log('right away 2', arr);

    请注意,尽管在代码中是“第一个”,但传递给setTimeout() 的函数在未来(至少)一秒后执行。这是一个异步的,而不是同步的代码。

    【讨论】:

    • 哇。我刚学会。说得好。感谢您将这些 cmets 放在代码的一侧。这有很大帮助。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2021-03-16
    • 2013-04-22
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 2017-07-18
    • 2020-11-16
    • 1970-01-01
    相关资源
    最近更新 更多