【问题标题】:How to use result of server method within client side collection hook?如何在客户端收集挂钩中使用服务器方法的结果?
【发布时间】:2015-05-03 20:42:54
【问题描述】:

我正在尝试使用 matb33:collection-hooks 设置一些服务器和客户端 before.insert 和 before.update 挂钩,我需要使用服务器端方法的结果来增强文档。

由于客户端缺少某些库,我无法纯粹在客户端上执行此操作。

我不能纯粹在服务器上执行此操作,因为我需要立即获得结果,否则 UI 会闪烁和跳动太多。

问题是,服务器端方法在客户端被异步调用,因此我没有定义。

有没有一种干净的方法来运行阻塞函数,我可以在客户端 before.insert / before.update 钩子中使用它来从服务器获取一些结果?

编辑: 在继续使用客户端存根之前,我必须有权访问服务器端函数(或方法)的结果。因此,我的问题归结为:

如何在客户端创建一个阻塞函数来等待服务器端函数的结果。

我无法在客户端模拟或模拟临时值。我不需要/想要延迟补偿。阻止是我需要和想要的。

【问题讨论】:

    标签: javascript asynchronous meteor


    【解决方案1】:

    使用与您在客户端使用的功能相同的功能,但是向集合对象添加一个标记,例如 readyForServer : false。在客户端对对象执行了所需的操作后,设置readyForServer : true,然后观察服务器上的变化,专门寻找readyForServer === true 属性。下面是服务器代码外观的示例。我假设您已经有一个有效的客户端钩子:

    // Watch For File Additions
    Files.find().observeChanges({
      added : function (id, fields) {
         // Don't want to watch added
      },
      changed : function (id, fields) {
        if (fields.readerForServer) {
          // Complete server side actions
    
        }
      }
    }); 
    

    【讨论】:

    • 我的要求是我正在开发的一个包,它需要在客户端上是透明的,不需要修改代码并且应该是有选择性的。像这样在服务器上的猴子补丁模式需要开发人员或包代码来设置观察者,无论如何。不过还是谢谢你的想法。
    【解决方案2】:

    您可以使用存根。由于服务器存在延迟,如果您想避免闪烁,您可以在服务器等待结果时临时添加“虚拟”字段。

    您需要做的就是在客户端为Meteor.call 创建一个匹配方法。此方法将在模拟模式下运行,仅用于 UI。

    //客户端

    Meteor.call("insert_my_doc", { value: '2'});
    
    Meteor.methods({
        insert_my_doc: function(doc) {
            doc.added_value = 'this is an added value';
            MyCollectionWithHooks.insert(doc);
        }
    });
    

    //服务器端

    Meteor.methods({
        insert_my_doc: function(doc) {
            MyCollectionWithHooks.insert(doc);
        }
    });
    
    MyCollection.before.insert(function(doc) {
        doc.added_value = 'something';
    });
    

    这里的附加值将是“2”而不是什么,然后将自身更正为“某物”。当然你可以把它变成其他任何东西。

    如果您更具体地了解要对文档进行的更改,我可以根据您的需要修改答案。但这将是这样的,因为您必须让客户端上的某些东西在服务器响应时提供虚假的临时值(不会立即响应)。

    关于你的最后一个问题,它不可能以任何方式运行阻塞方法(没有 ES6 功能,这些功能还没有完全发布并且在每个人的浏览器上都不可用)。

    如果您觉得这可以满足您的需要,您可以使用生成器:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators

    【讨论】:

    • 谢谢,但在继续创建文档之前,我肯定需要客户端上的服务器结果。这不是我可以替代或模拟客户的结果。我必须在插入继续之前等待该结果,即使它在存根中。
    • @SerkanDurusoy 你必须期待一些 UI 模拟。使用阻塞解决方案,如果您决定使用生成器,基本上会冻结 UI,这会更糟。也许您可以在方法等待完成时放入加载屏幕?
    • 我对阻塞 UI 没问题。事实上,正如我解释的那样,这正是我想要的。
    • @SerkanDurusoy 我已经为这种情况提供了一些你可以做的事情,你可以使用生成器。恐怕浏览器需要启用 ES6。由于客户端 javascript 的限制,无法解决此问题。
    • 感谢 Akshat,我的直觉告诉我同样的情况,不幸的是我还不熟悉 ES6 概念。如果您可以使用对服务器端流星方法的“阻塞异步”调用的基本示例来编辑您的答案,我会继续将此标记为已接受的答案以供将来参考。
    猜你喜欢
    • 2018-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多