Можно ли замедлить обновление трекера на Метеоре? - PullRequest
0 голосов
/ 07 января 2019

У меня есть приложение, на которое подписано много данных, но мне не нужно, чтобы оно загружалось в реальном времени. Можно ли заставить Tracker обновлять данные медленнее, скажем, на 5 секунд? Я работаю с React и использую withTracker (). Спасибо!

Ответы [ 2 ]

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

Нет встроенного способа задержки реактивности в метеоре,

Возможно, я смогу решить эту проблему несколькими способами

1) точно так же, как @jankapunkt сказал, что вы можете использовать Meteor.methods для извлечения данных, а затем вы можете вызывать один и тот же метод каждые 5/10 секунд, используя Meteor.setInterval и обновлять данные

2) Если вы хотите использовать pub / sub, вы можете подписаться на данные, и как только подписка будет готова, установите данные в переменной reactiveDict или reactivieVar и через каждые 5/10 секунд используйте эту переменную с помощью собирать данные и использовать эту переменную для отображения данных в пользовательском интерфейсе

образец кода для второго варианта в Blaze, вы можете использовать setState в реакции вместо reactiveDict

import { Template } from "meteor/templating";
import { ReactiveDict } from "meteor/reactive-dict";

Template.myTemplate.onCreated(function() {
  const t = this;
  t.dataDict = new ReactiveDict();
  t.dataDict.set('users', []);
  t.subscribe('my.publication');
})

Template.myTemplate.hlepers(function() {
  users() {
    const t = Template.instance();
    return t.dataDict.get('users') || [];
  }
})

const startInterval = (t) => {
  t.interval = Meteor.setInterval(function() {
    const res = myCollection.find({}).fetch();
    t.dataDict.set('users', res);
  }, 5000);
};

Template.myTemplate.onRendered(function() {
  const t = this;

  t.autorun(function() {
    if (t.subscriptionsReady()) {
      const res = myCollection.find({}).fetch();
      t.dataDict.set('users', res);
      startInterval()
    }
  })
});

Template.myTemplate.onDestroyed(function() {
  const t = this;
  // clears interval
  Meteor.clearInterval(t.interval);
})
0 голосов
/ 08 января 2019

Можно ли сделать так, чтобы Tracker обновлял данные медленнее, скажем, на 5 секунд?

Трекер запускается, если изменяются реактивные данные, поэтому каждое изменение данных, которые хранятся внутри Трекера (ReactiveVar, ReactiveDict, Subscription), вызывает повторный запуск.

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

Тогда вам обязательно нужно удалить подписку и получить данные с помощью Meteor метода .

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

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

Обратите внимание, что по умолчанию вы теряете реактивность, но вы можете поместить полученные данные либо в ReactiveVar / ReactiveDict, либо создать только локальный клиент Mongo.Collection.

Если вы хотите сохранить преимущества использования Mongo.Collection, вам просто нужно вставить полученные документы в новую локальную коллекцию:

import { Mongo } from 'meteor/mongo'

const LocalCollection = new Mongo.Collection('myLocalData') // should have an own unique name or null

и затем вызовите свой Метод внутри вашего компонента React (но не метода render):

// call a Meteor.method, pass some arguments, if required
// and parse the resulting documents array.
Meteor.call('getMyDataFromMethod', {foo:'bar'}, (err, documents) => {
  if (err) {
    // handle err
  } else {
    documents.forEach(doc => {
      // update existing docs if present
      // or insert as new into local collection
      if (LocalCollection.findOne(doc._id)) {
        LocalCollection.update(doc._id, { $set: doc })
      } else {
        LocalCollection.insert(doc)
      }
    })
  }
}) 

Поскольку ваши документы уже содержат _id, они будут сохранять _id при вставке в локальную коллекцию.

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

После добавления в локальную коллекцию вы можете использовать ее так же, как в своем коде.

...