Загрузите все документы одновременно. Не прогрессивно - PullRequest
0 голосов
/ 05 мая 2019

Когда я запускаю команду .fetch (), она сначала возвращает ноль, затем говорит, что у меня есть 100 документов, и она будет продолжать загружаться с 1 до 100, а счетчик постоянно обновляет с 1 до 100.Я не хочу, чтобы это случилось.Я хочу, чтобы все результаты отображались сразу после завершения процесса извлечения.

Кроме того, как я могу отобразить соответствующее сообщение для пользователя, если нет документов?Метод fetch у меня не работает, так как сначала он возвращает 0, и, следовательно, «секунду, пока не найден документ» мигает в течение секунды.

dbName.find({userID:"234234"}).fetch()

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

Ответы [ 3 ]

1 голос
/ 05 мая 2019

Я не хочу, чтобы это случилось. Я хочу, чтобы все результаты отображались сразу после завершения процесса извлечения

Чтобы действительно получить все документы сразу на клиенте, вам нужно написать метод Meteor, который возвращает все документы:

Meteor.methods({
  'allDocs' () {
    return dbName.find({userID:"234234"}).fetch()
  }
})

Обратите внимание, что вам нужно вызвать fetch на курсоре, чтобы вернуть документы, в противном случае вы столкнетесь с "ошибкой отклонения необработанного обещания".

Тогда позвоните клиенту как обычно. Вы даже можете добавить документы в свою локальную коллекцию на стороне клиента, не влияя на разрешение / запрет (которое по умолчанию должно быть отключено / запрещено):

Meteor.call('allDocs', (err, documents) => {
  // ... handle err
  // all client collections have a local collection accessible via ._collection
  const localCollection = dbName._collection 
  documents.forEach(doc => localCollection.insert(doc))
})

Преимущества:

  • Немедленно возвращает все документы
  • Меньше потребляемых ресурсов (публикация не требуется)
  • Работает с инструментами кэширования, такими как ground: db, для создания приложений, работающих в автономном режиме

Недостатки:

  • Вы должны максимально ограничить запрос и доступ к своим коллекциям, используя методы (используя mdg: validated-method), что может потребовать гораздо больше усилий, чем показано в этих примерах
  • Не реагирует! Если вам нужна реактивность на клиенте, вам нужно включить Tracker и реактивные источники данных (ReactiveVar и т. Д.), Чтобы обеспечить приличный реактивный пользовательский опыт
  • Ручная синхронизация может расстраивать и приводить к ошибкам
0 голосов
/ 05 мая 2019

Ваш вопрос на самом деле о подписке и состоянии готовности.Пока он еще не готов, вы можете показать загрузочную страницу, и, как только она появится, вы можете запустить .fetch(), чтобы получить весь массив.Эта логика может быть введена в ваш вызов withTracker, например:

export default withTracker((props) => {
  const sub = Meteor.subscribe('users');
  return {
    ready: sub.ready(),
    users: sub.ready() && Users.find({userID: props.userID}).fetch()
  };
})(UserComponent);

Затем в вашем компоненте вы можете решить, следует ли отображать счетчик (пока ready == false) или пользователей.

0 голосов
/ 05 мая 2019

Ваш вопрос мне не совсем понятен с точки зрения инструментов и т. Д. (, пожалуйста, укажите, какую библиотеку коннектора базы данных вы используете ), но, во-первых, учитывая, что вы делаете доступ к базе данных, скорее всего, ваш Вызов ".fetch ()" - это не функция синхронизации, а асинхронный вызов, который, скорее всего, обрабатывается обещанием.

Во-вторых, если вы используете реагирование, вы хотите установить новое состояние только после того, как вернете все результаты.

Если выборка - это обещание, просто сделайте:

dbName.find({userID:"234234"}).fetch().then(results =>
  setState({elements:results.data}) // do your processing accordingly
}

Вызывая setState только внутри обещания, вы всегда получаете все результаты, извлеченные в этот момент, и только с этим вы обновляете состояние своего компонента с помощью функции setState - либо используя класс реагирующего компонента this.setState, либо с помощью ловушек как useState (намного чище).

...