Meteor 流星服务器延迟
我觉得我做错了什么,因为我的结果似乎违背了Meteor为提高速度而模拟客户机/服务器交互的基调。当我使用Meteor.call()执行任何类型的数据库更新时,应用程序必须等待到服务器的往返,这通常会导致响应缓慢或用户按下按钮两次。我只是想确定我做得对。以下是我正在做的: 客户端:Meteor 流星服务器延迟,meteor,Meteor,我觉得我做错了什么,因为我的结果似乎违背了Meteor为提高速度而模拟客户机/服务器交互的基调。当我使用Meteor.call()执行任何类型的数据库更新时,应用程序必须等待到服务器的往返,这通常会导致响应缓慢或用户按下按钮两次。我只是想确定我做得对。以下是我正在做的: 客户端: Template.shot.events({ 'change #shot-status-select': function (event, template) { var new_status = $(even
Template.shot.events({
'change #shot-status-select': function (event, template) {
var new_status = $(event.target).val();
var shot_id = Session.get('current_shot_id');
Meteor.call('setShotStatus', shot_id, new_status, function (error, result) {
if (result) {
feedbackSuccess('Status changed to <b>'+new_status+'</b>');
} else {
feedbackError('Status change failed');
console.log(error);
}
});
},
});
...
'setShotStatus': function(shot_id, status) {
var result = Shots.update({'_id': shot_id}, {$set: {'status': status}});
if (result) {
return true;
} else {
return false;
}
},
这里发生了一些事情,使您的方法无法得到延迟补偿(它正在进行到服务器的完整往返) 首先,如果使用回调在客户机上执行,它将始终等待来自服务器的结果。不幸的是,您不能同步编写它,因为
调用
在客户端上总是返回未定义的
,并且您需要返回的结果
如果您真的想要存根的结果,您需要像这样重写它:
var args=[shot_id,new_status];
var result=Meteor.apply('setShotStatus',args,{returnStubValue:true});
如果(结果)
反馈成功('状态更改为'+新状态+'');
注意:如果可能出现错误,您应该将调用
包装在try
/catch
中。还请注意,在一般情况下,客户端和服务器返回值并不总是匹配的,因此请记住使用此技术
接下来,您的方法定义需要位于客户端和服务器代码的共享位置(将其放在lib
下或包中是一个不错的选择)。如果客户端没有方法代码,它就不能模拟它
建议阅读:
- “延迟补偿”文章在
- 谢谢你,大卫。你的回答让我走上了正确的轨道,但我认为有几个金块似乎太多了,无法在评论中讨论。我发现的主要问题是:
回到“Meteor zero latency”(流星零延迟)承诺的挑战很简单,就是将我所有的“服务器”方法移动到
lib
目录
实际上,没有代码更改。在使客户机和服务器都可以访问这些方法之后,Meteor完成了所有繁重的工作,首先在客户机上执行,然后用服务器结果检查结果
David的回答说,使用回调将始终等待服务器的结果。我发现这在一定程度上是正确的,因为它将异步等待结果。尽管这取决于方法的可访问性,但它可能是您所经历的客户端的结果,而不是来自服务器的往返。不使用回调将始终返回未定义
,因此结果
在给定示例中不起作用
最后,出于安全原因,我将真正的私有逻辑移到了纯服务器目录
以下是代码结果:
客户端/shot.js
Template.shot.events({
'change #shot-status-select': function (event, template) {
var new_status = $(event.target).val();
var shot_id = Session.get('current_shot_id');
Meteor.call('setShotStatus', shot_id, new_status, function (error, result) {
if (!(result)) {
feedbackError('Status change failed');
console.log(error);
}
});
},
});
Meteor.methods({
'setShotStatus': function(shot_id, status) {
var result = Shots.update({'_id': shot_id}, {$set: {'status': status}});
if (result) {
return true;
} else {
return false;
}
},
});
lib/methods.js
Template.shot.events({
'change #shot-status-select': function (event, template) {
var new_status = $(event.target).val();
var shot_id = Session.get('current_shot_id');
Meteor.call('setShotStatus', shot_id, new_status, function (error, result) {
if (!(result)) {
feedbackError('Status change failed');
console.log(error);
}
});
},
});
Meteor.methods({
'setShotStatus': function(shot_id, status) {
var result = Shots.update({'_id': shot_id}, {$set: {'status': status}});
if (result) {
return true;
} else {
return false;
}
},
});
Meteor.call
通常返回未定义的。我假设如果在客户端和服务器上都定义了该方法,Meteor.call
返回正确的值?是的,为了返回值,必须在客户端(存根)上定义。有关更完整的描述,请参阅。您是正确的-我最初的回答在如何从存根调用的结果中读取值方面是错误的。我已经用apply
的一个例子纠正了这个问题,这个例子应该适用于您介绍的简单案例。谢谢您的帮助,David。