【问题标题】:Meteor.call in client doesn't wait when the called method has another call inside当被调用方法内部有另一个调用时,客户端中的 Meteor.call 不会等待
【发布时间】:2018-08-29 05:34:45
【问题描述】:

我正在遵循我所读到的作为使用 Meteor.call 的标准方法,但在这种情况下它的行为很奇怪:

客户:

Template.sometemplate.events({
    'submit .somebutton'(event){
         ...
         Meteor.call('stuff.someMethod', param1, function (err, res){
              console.log(err);
              console.log(res);
         };
    }
})

服务器/api/stuff.js:

Meteor.methods({
    'stuff.someMethod'(param1){
         ...
         Meteor.call('otherstuff.someOtherMethod', param1, function(err, res){
                  if(err){ throw new Meteor.Error(400,'wrong things');}
                  if(res) { return 'ok';}
             }
         );
    }
})

服务器/api/otherstuff.js:

Meteor.methods({
    'otherstuff.someOtherMethod'(param1){
         ...
         return OtherStuff.findOne(query);
    }
})

在客户端,我单击并立即看到 err 和 res 的 console.log 未定义。而在应用程序的其他部分,当客户端调用服务器方法时,它并没有调用另一个方法,客户端在执行异步回调之前等待答案。

我在调用另一个服务器方法的服务器方法中使用 Meteor.call 的方式一定有问题。场景是,例如我想插入一个文档,同时我想检查一些值,以便将它链接到其他集合中的其他文档。

非常感谢, T.

【问题讨论】:

    标签: meteor async-await


    【解决方案1】:

    在服务器上同步调用

    在服务器上使用Meteor.call 不需要回调,除非你真的想在服务器端异步工作。

    如果没有在服务器上传递回调,则方法调用 将阻塞直到方法完成。它最终会返回 方法的返回值,否则会抛出异常 方法抛出异常。 (可能映射到 500 服务器错误,如果 异常远程发生,它不是 Meteor.Error 异常。)

    您可以返回结果而不是传递回调

    return Meteor.call(...)
    

    或将其分配给用于进一步处理的变量。

    const retVal = Meteor.call(...)
    


    更好的方法:外部化共享代码

    如果两个流星方法依赖于相同的代码(例如,一个调用另一个),您应该将此代码提取到一个共享函数中。这也使测试和跟踪错误变得更加容易。

    server/api/common.js

    export const sharedFunction = function(param1) {
        // ... do somethin
        return OtherStuff.findOne(query); 
    }
    

    服务器/api/stuff.js:

    import { sharedFunction } from './common.js';
    
    Meteor.methods({
        'stuff.someMethod'(param1){
             // ...
             const temp = sharedFunction(param1);
             // ...
             return result; // or temp if this should be returned to client
        }
    })
    

    server/api/otherstuff.js

    import { sharedFunction } from './common.js';
    
    Meteor.methods({
        'otherstuff.someOtherMethod'(param1){
             return sharedFunction(param1);
        }
    });
    

    使用sharedFunction 遵循DRYSingle Point of Failure 的概念。

    【讨论】:

    • 谢谢,我只是听从了你的建议: const retVal = Meteor.call(param1);并将它包装成一个try catch(让它工作,然后我会做得很好)。客户端现在等待响应。也感谢分享的方法,确实有道理。
    猜你喜欢
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    • 2012-05-31
    • 1970-01-01
    • 1970-01-01
    • 2019-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多