如何跳出querySnapshot forEach循环方法?

10

我想从一个 forEach 循环中跳出。考虑以下代码:

db.collection('users').get().then(querySnapshot => {
        if (!querySnapshot.empty) {
            querySnapshot.forEach(doc => {
                let data = doc.data()
                if (data.age == 16) {
                    break //this is not working
                }
            })
        }
    }
)

这份文档并未提到如何跳出 forEach 循环。

3个回答

38

不要直接在QuerySnapshot上使用forEach,而应该直接迭代其docs属性,它只是一个普通的javascript数组。编写一个for循环,可以根据需要使用break

for (var i in querySnapshot.docs) {
    const doc = querySnapshot.docs[i]
    if (make_some_decision_here) {
        break
    }
}

1
我在寻找querySnapshot上的forEach替代方案,你救了我的一天。 - Kundan

0

根据这里的https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

除了抛出异常,没有其他方法可以停止或中断forEach()循环。如果您需要这样的行为,则forEach()方法是错误的工具。

唯一停止或中断forEach()循环的方法是抛出异常
尝试以下替代方案
一个简单的循环
一个for...of循环
Array.prototype.every()
Array.prototype.some()
Array.prototype.find()
Array.prototype.findIndex()


1
Firebase的querySnapshot不是数组的实例。 - charlietfl
如果您只是阅读提供的文档,那么它会说 -> docs 不为空的 firebase.firestore.QueryDocumentSnapshot 数组 一个包含 QuerySnapshot 中所有文档的数组,请尝试对其进行迭代 - Chris Li
好的,那就建议对docs数组进行迭代,但是主对象的唯一迭代器方法是forEach,它是一个内部方法,不是Array.prototype.forEach()。 - charlietfl
forEach的回调函数需要一个非空的firebase.firestore.QueryDocumentSnapshot,它是一个数组docs。 - Chris Li
那又能怎么样呢……无法从forEach中跳出?你已经指出了这一点。 - charlietfl
请将以下与编程有关的内容从英语翻译成中文。仅返回已翻译的文本:https://dev59.com/91YN5IYBdhLWcg3w9MXr,如果必须使用forEach,请抛出异常。 - Chris Li

-1

.forEach 不提供直接的机制来实现早期退出。你最好的选择是抛出一个异常:

querySnapshot => {
  if (!querySnapshot.empty) {

    try {

      querySnapshot.forEach(doc => {
          let data = doc.data()
          if (data.age == 16) {
              // Throw an exception to break. Use a custom exception type to
              // distinguish it from other possible exceptions that could be
              // thrown
              throw EarlyExit; 

          }
      })

    } catch(exception) {

      // If the exception thrown is not our EarlyExit type, then re throw,
      // otherwise resume as if look with terminated
      if(exception !== EarlyExit) {
        throw exception
      }
    }
  }
}

或者,您也可以使用常规的for循环方法来实现更简单的查找中断:

for(const doc of querySnapshot) {
      let data = doc.data()
      if (data.age == 16) {
          break;
      }
}

如果使用for循环,类型“QuerySnapshot<DocumentData>”不是数组类型或字符串类型。 - utopia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接