Более чистый способ запросить коллекцию и вернуть данные в виде списка? - PullRequest
0 голосов
/ 24 января 2019

Похоже, что существует более чистый и оптимизированный способ запроса коллекции Firestore, вызова doc.data() для каждого документа, а затем возврата массива в качестве результата.Порядок, в котором документы помещаются в массив результатов чувствует случайность.

В этом коде много шагов:

  1. Новая переменная resultсоздан
  2. Сделан запрос для получения коллекции «историй»
  3. Для каждого документа мы вызываем doc.data()
  4. Мы выдвигаем каждый документ к resultarray
  5. Возвращает массив result
  function getStories() {
    var result = [];
    db.collection('stories').get().then(querySnapshot => {
        querySnapshot.forEach(doc => result.push(doc.data()));
    })
    return result;
  }

Код работает нормально, но кажется, что мы можем написать этот код более чистым способом с меньшим количеством шагов.

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Код, которым вы поделились, на самом деле не работает, как прокомментировал Джордж.Поскольку Firestore загружает данные асинхронно, вы всегда возвращаете массив перед загрузкой данных.Ваш массив будет пуст, вы хотите вернуть обещание, которое разрешается после загрузки данных.Что-то вроде этого:

function getStories() {
  var result = [];
  return db.collection('stories').get().then(querySnapshot => {
    querySnapshot.forEach(doc => result.push(doc.data()));
    return result;
  })
}

Таким образом, это, в основном, добавило два оператора возврата, которые заставляют ваш result всплывать, а затем возвращаться как обещание от getStories.Чтобы вызвать это, вы должны сделать:

getStories().then(result => {
  console.log(result.length);
})

, который будет записывать правильное количество результатов.

0 голосов
/ 24 января 2019

Сначала определите функцию map для использования с firebase (с именем mapSnapshot, потому что она предназначена специально для использования с firebase):

const mapSnapshot = f => snapshot => {
  const r = [];
  snapshot.forEach(x => { r.push(f(x)); });
  return r;
}

Тогда вы можете просто работать с Promise и mapSnapshot:

function getStories() {
  return db.collection('stories').
    get().
    then(mapSnapshot(doc => doc.data()));
}

Пример использования:

getStories().then(docs => ... do whatever with docs ...)

Если честно, код не будет меньше , если использовать его как разовое решение. Но здесь есть все, что нужно, это позволяет создавать многократно используемые абстракции . Так, например, вы могли бы использовать mapSnapshot для создания snapshotToArray функции, которую можно использовать повторно всякий раз, когда вам нужно преобразовать DataSnapshot из firebase в обычный Array:

const snapshotToArray = mapSnapshot(x => x);

Обратите внимание: это не зависит от имени какой-либо коллекции . Вы можете использовать его с any DataSnapshot из any collection, чтобы преобразовать его в Array!

Это еще не все. Вы также можете легко создать функцию из содержимого DataSnapshot в обычный Array с содержимым в нем:

const readDocsData = mapSnapshot(x => x.data());

Опять же, это не выглядит большой проблемой - пока вы не поймете, вы также можете создать функцию fromFirebase, которая позволяет запрашивать различные наборы данных:

const fromFirebase = (name, transform = x => x) => {
  return db.collection(name).get().then(transform);
}

И что вы можете затем использовать следующим образом:

fromFirebase('stories', readDocsData).then(docs => {
  // do what you want to do with docs
});

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

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