【问题标题】:how to evaluate firestore query before executing the next lline如何在执行下一行之前评估 Firestore 查询
【发布时间】:2018-10-07 09:59:37
【问题描述】:

我有一个函数应该返回给定集合中的文档数据列表。

function _getPrevActivity(){

let historyCollectionRef =  firestore.collection("/users/RSgNDLPxT2aAERQutXEEyhHHJYk1/agreements/DkRdZ5kHi2g7MlBV3Kjq/test/test-something/records/15/history");
let value = [];
let wait;
    historyCollectionRef.orderBy('timeStamp').onSnapshot(querSnap => {
    querSnap.forEach(doc => {
        value.push(doc.data())
        console.log(value.length, " length")

        })
    console.log(value)
    return value;

    });

return value;

}

此函数始终返回 [] 并稍后执行 firestore 查询。

PS:我是 Node 环境的新手,我编写函数的方式也可能有问题。

【问题讨论】:

  • onSnapshot 立即返回,这意味着您的函数将返回 value 与其原始值保持不变。您传递给onSnapshot 的回调将在稍后查询结果准备好时被调用。换句话说,你不能只让一个函数返回一个异步产生的值。 stackoverflow.com/questions/14220321/…
  • 还请记住,对 onSnapshot 的回调可能会被调用多次,每次更改文档时调用一次。如果您只需要一个值,请改用get()
  • 嗯,这很可悲,所以如果不更改 firestore api,就没有办法实现这一点吗?我已将onSnapshot 更改为get
  • 带有 promise 的异步编程(如 get() 返回的那些)在 javascript 和 node.js 中非常常见。你真的无法避免。 medium.com/google-developers/…
  • 嗯,看完文章说的有道理,只需要我自己重构一下

标签: javascript node.js firebase firebase-realtime-database google-cloud-firestore


【解决方案1】:

您犯了处理异步调用的典型错误,就像处理同步编程一样。

我将您的代码重组如下:

function _getPrevActivity() {
      let value = [];
      let wait;
      const path = "/users/RSgNDLPxT2aAERQutXEEyhHHJYk1/agreements/DkRdZ5kHi2g7MlBV3Kjq/test/test-something/records/15/history";

      return firestore.collection(path).orderBy('timeStamp')
        .onSnapshot(querSnap => {
          querSnap.forEach(doc => {
            value.push(doc.data())
            console.log(value.length, " length")
          });
          console.log(value)
          return value;
        }).catch(error => {
          console.log(error);
          return value;
        });
    }

    // calling function
    function otherFunc() {
      _getPrevActivity().then(value => {
        // do something with value...
        // value will not be an empty array now
        console.log(value);
      }).catch(console.log);
    }

你在这里犯的错误是你不能真正从匿名函数querSnap => {...返回一个值,除非你也从你想要返回值的函数返回封闭的承诺。

此外,要从异步调用的 return 访问值,需要使用我已添加到下面代码中的 then() 子句。

【讨论】:

  • 我试过了,但在otherFunc 中抛出错误,_getPrevActivity)(...).then is not a function
  • 您使用的语法是否正确?这是_getPrevActivity().then(value) 而不是_getPrevActivity)(...).then 你在评论中写的。
猜你喜欢
  • 1970-01-01
  • 2014-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-11
相关资源
最近更新 更多