流星服务器延迟

时间:2015-11-21 07:19:15

标签: meteor

我觉得我做错了,因为我的结果似乎违背了Meteor模拟客户/服务器交互速度的本质。当我使用Meteor.call()进行任何类型的数据库更新时,应用程序必须等待往返服务器,通常会导致响应缓慢或用户按两次按钮。我只是想确保我正确地做到这一点。这就是我正在做的事情:

客户端:

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;
    }
},

2 个答案:

答案 0 :(得分:2)

这里有一些事情阻止你的方法被延迟补偿(它完成了到服务器的完整往返)。

首先,如果您在客户端上使用回调执行Meteor.call,它将始终等待来自服务器的结果。不幸的是,您无法同步编写它,因为call将始终在客户端返回undefined,并且您需要返回的结果。

如果你真的想要存根的结果,你需要像这样重写它:

var args = [shot_id, new_status];
var result = Meteor.apply('setShotStatus', args, {returnStubValue: true});
if (result)
  feedbackSuccess('Status changed to <b>'+new_status+'</b>');

请注意,如果可能出现错误,您应将call包裹在try / catch中。另请注意,客户端和服务器返回值在一般情况下并不总是匹配,因此请考虑使用此技术。

接下来,您的方法定义需要位于客户端和服务器代码的共享位置(将其放在lib下面或包中是不错的选择)。如果客户没有方法代码,则无法对其进行模拟。

推荐阅读:

答案 1 :(得分:0)

谢谢大卫。你的回答让我走上了正确的道路,但我认为那里有几个小块似乎在评论中讨论太多了。我发现的主要是:

回到“流星零延迟”承诺的挑战就像将所有“服务器”方法移动到lib目录一样简单。

从字面上看,没有代码更改。在让客户端和服务器都可以访问这些方法之后,Meteor首先在客户端执行了所有繁重的操作,然后使用服务器结果检查结果。

David的回答说使用回调将始终等待服务器的结果。我发现这部分是正确的,因为它会异步地等待结果。虽然取决于您的方法的可访问性,但它可能是您遇到的客户端的结果,而不是来自服务器的往返。不使用回调将始终返回undefined,因此result将无法在给定示例中使用

最后,出于安全原因,我将真正的私有逻辑移动到仅服务器目录。

以下是代码结果:

<强>的客户机/ 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);
        }
    });
},
});

<强> LIB / methods.js

Meteor.methods({
    'setShotStatus': function(shot_id, status) {
        var result = Shots.update({'_id': shot_id}, {$set: {'status': status}});
        if (result) {
            return true;
        } else {
            return false;
        }
    },
});