Как я могу дать обещание прекратить после получения x результатов в Firestore - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть этот код, который проверяет, существуют ли мои идентификаторы userContacts в другой коллекции, и я возвращаю все совпадения.

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 совпадений, а не все, так как позже яу меня будет миллион записей, и я хочу сократить время обработки.

Как я могу заставить Promise.all останавливаться, когда в commonNumbers есть X элементов?

Ответы [ 3 ]

0 голосов
/ 12 февраля 2019

Сокращение времени обработки без "остановки" обещаний

Вы не можете действительно давать обещания стоп .Но так как вы хотите уменьшить количество вызовов базы данных , вы можете выборочно выполнить свои обещания .

ДляНапример, вы можете включить условное выражение в вашу функцию 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));

Примечание

Хотя это может уменьшить ваши вызовы в базе данных, фактическое количество вызовов может быть немного выше, чем ваше максимум указано.Это связано с асинхронной природой вызовов

0 голосов
/ 12 февраля 2019

Вместо того, чтобы нарушать обещание между ними, я бы предложил вам использовать метод limit do firestore.

Вы можете запросить только X записей, и этот X может быть жестко закодирован.или может прийти от пользователя.Что-то вроде:

documentRef.orderBy("name").limit(3).get()
0 голосов
/ 12 февраля 2019

В настоящее время нет реализации отменяемых обещаний (более подробную информацию можно найти здесь введите описание ссылки здесь ),

Если вы хотите, вы можете определить свою собственную оболочку "отменяемого обещания"нормальное обещание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...