我有一个应用程序,其中订阅了很多数据,但我并不需要实时加载。是否可以使Tracker刷新数据的速度变慢(例如5秒)?我正在开发React并使用withTracker()。谢谢!
答案 0 :(得分:1)
能否使Tracker刷新数据的速度变慢(例如5秒)?
如果反应性数据发生更改,则Tracker会运行,因此,跟踪器中保存的数据(ReactiveVar,ReactiveDict,Subscription)中的每一次更改都会导致重新运行。
...订阅了很多数据,但我并不需要实时加载。
然后,您绝对应该删除订阅并通过Meteor method获取数据。
如果集合更新,则发布会立即将数据发送给订阅者。如果您不依赖此功能,则基本上是在浪费服务器和网络资源,并且如果您的应用程序可以吸引到更高级别的用户,资源将成为大问题。
使用“方法”,如果您连续调用几次,则将有一些数据开销,因为数据是从集合中再次发送的(而发布仅发送增量),但是您也可以更好地控制此行为。
请注意,默认情况下您会松开反应性,但是您可以将接收到的数据放入ReactiveVar / ReactiveDict或创建仅本地客户端的$pattern = '(.*)Name=".*" (.*)'
$str = 'Other parts of the string Name="SomeRandomAmountOfCharacters" blah blah'
$ret = $str -match $pattern
$out = $Matches[1]+$Matches[2]
$str
"===>"
$out
。
如果您想保留使用Mongo.Collection的好处,只需将收到的文档插入新的本地集合中即可。
Mongo.Collection
,然后在React组件(而不是import { Mongo } from 'meteor/mongo'
const LocalCollection = new Mongo.Collection('myLocalData') // should have an own unique name or null
方法)中调用Method:
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
而不是游标返回获取的文档。
添加到本地集合后,您可以像在代码中一样使用它。
答案 1 :(得分:0)
没有内置的方法来延迟流星的反应,
我可能有几种解决方法
1)就像@jankapunkt所说的那样,您可以使用Meteor.methods提取数据,然后可以使用Meteor.setInterval
每5/10秒调用相同的方法并更新数据
2)如果要使用pub / sub,则可以订阅数据,一旦订阅准备好,就可以在reactiveDict
或reactivieVar
变量中设置数据,每5/10秒使用一次使用收集数据更新此变量,并使用此变量在ui中显示数据
大火中第二个选项的示例代码,您可以在反应中使用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);
})