在Firestore中获得x结果后,我如何才能兑现承诺

时间:2019-02-12 10:25:47

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

我有这段代码正在检查我的userContacts ID是否在另一个集合中,并且我将返回所有匹配项。

async function fetchCommonNumbers() {
    var commonNumbers = [];

    let contactsReference = admin.firestore().collection("user_contacts").doc("iNaYVsDCg3PWsDu67h75xZ9v2vh1").collection("contacts");
    const dbContactReference = admin.firestore().collection('db_contacts_meta');

    userContacts = await contactsReference.get();
    userContacts = userContacts.docs;

    await Promise.all(
        userContacts.map(userContact => {
            const DocumentID = userContact.ref.id;
                //Check if Document exists
                return dbContactReference.doc(DocumentID).get().then(dbContact => {
                    if (dbContact.exists) {
                        console.log(DocumentID);
                        commonNumbers.push(dbContact.data());
                    }
                });
        }));

    return Promise.resolve(commonNumbers);

}

我只需要返回X个匹配项,而不是全部,因为以后我将拥有一百万条记录,并且我想减少处理时间。

当commonNumbers中包含X个项目时,如何使Promise.all停止?

3 个答案:

答案 0 :(得分:0)

当前没有实现可撤销的承诺(更多信息可以在enter link description here上找到),

如果需要,您可以定义自己的“可取消承诺”,以包装正常的承诺。

答案 1 :(得分:0)

减少处理时间而无需“停止”承诺

您不能真正兑现承诺停止。但是,由于您要减少数据库调用次数,因此您可以 选择性地兑现您的诺言

例如,您可以在map函数中包含条件语句。像这样

  • if commonNumbers.length < maxLength然后给我一个承诺,其中包含数据库调用
  • 否则,只需解析一个随机值(例如我的示例中的false

您的诺言仍然存在,但是您将将数据库调用的数量限制为必要的。看起来像这样

const arr = [1, 2, 3, 4, 5, 6];
const buffer = [];
const maxLenBuffer = 3;

const p = Promise.all(
  arr.map(n => {
      if (buffer.length < maxLenBuffer) {
          buffer.push(n);
          return Promise.resolve(n);
      } else {
          // There's still a promise to be resolved, but it's not a HTTP call
          // This gives you the gain of performance you're looking for
          return Promise.resolve(false);
      }
  })
);

p.then(() => console.log(buffer));

注意

虽然此可以减少您的数据库调用,但实际的调用次数可能比您指定的最大稍高。这是由于调用的异步性质

答案 2 :(得分:0)

建议您不要使用limit方法来执行存储操作,而要避免违反承诺。

您只能查询X个记录,该X可以是硬编码的,也可以来自用户。像这样:

documentRef.orderBy("name").limit(3).get()