【问题标题】:How to break out of the querySnapshot forEach loop method?如何打破 querySnapshot forEach 循环方法?
【发布时间】:2019-02-14 10:34:18
【问题描述】:

我想跳出 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
                }
            })
        }
    }
)

documentation 没有提及中断 forEach 循环

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 我在 querySnapshot 上寻找 forEach 的替代品,你救了我的命。
    【解决方案2】:

    据此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()

    【讨论】:

    • Firebase querySnapshot 不是 Array 的实例。
    • 如果您只是阅读您提供的文档,它会显示 -> docs non-null Array of non-null firebase.firestore.QueryDocumentSnapshot QuerySnapshot 中所有文档的数组,请尝试对其进行迭代
    • 好吧,然后建议迭代 docs 数组,但主对象的唯一迭代器方法是 forEach,它是一个内部方法,不是 Array.prototype.forEach()
    • forEach 的回调采用非 null firebase.firestore.QueryDocumentSnapshot,它是 docs,它是一个数组。
    • 这有什么帮助...不能脱离 forEach?你已经指出了这一点
    【解决方案3】:

    .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;
          }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-15
      • 2023-03-26
      • 2010-10-07
      • 2011-12-08
      • 1970-01-01
      相关资源
      最近更新 更多