Vue - Firebase提交行动范围问题?

时间:2018-04-19 01:30:15

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

我有这行代码不起作用:

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数组,因此它可以在外部提交。我不知道为什么会这样。想法?

1 个答案:

答案 0 :(得分: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()的函数将在未来一秒钟后执行(至少)。它是一个异步的,而不是同步的代码。