如何等待meteor调用响应,然后在javascript中执行其他语句?

如何等待meteor调用响应,然后在javascript中执行其他语句?,javascript,node.js,meteor,angular-meteor,Javascript,Node.js,Meteor,Angular Meteor,我在meteor中有两个meteor调用客户端事件,我想在其中一个接一个地执行。但在我调试时,流程没有按照我希望的方式进行。 client.js Meteor.call('methodCall',param1,param2,param3,function (error, result) { if (error) console.log(error.reason); Session.set("xyz",result); }); var abc=Session.

我在meteor中有两个meteor调用客户端事件,我想在其中一个接一个地执行。但在我调试时,流程没有按照我希望的方式进行。

client.js

Meteor.call('methodCall',param1,param2,param3,function (error, result) {
    if (error) 
        console.log(error.reason);

    Session.set("xyz",result);
});

var abc=Session.get("xyz");

Meteor.call('methodCall',abc,param2,param3,function (error, result) {
    if (error) 
        console.log(error.reason);

    console.log("result: "+result);
    Session.set("cdf",result);
}); 

var pqr=Session.get("cdf");
正如您所看到的,这是我希望按顺序运行的代码,即一个接一个。但是当我调试代码时,我发现执行顺序是:

1. Meteor will be called
3. session.get("xyz") return undefined.
4. Meteor will be called
6. session.get("cdf") return undefined.
2. session.set() will have results as value.
5. session.get() will not have any value.

第二个meteor.call()将无法成功执行,因为第1个参数没有任何值,因为在第2步之前执行了第3步。那么,我有没有办法做到这一点,然后等待meteor调用完成以执行下一个指令

方法之一是稍微重新组织代码

Meteor.call('methodCall',param1,param2,param3,function (error, result) 
{
  if (error) console.log(error.reason);
  Session.set("xyz",result);
  var abc=Session.get("xyz");
  Meteor.call('methodCall',abc,param2,param3,function (error, result) 
  {
    if (error) console.log(error.reason);
    console.log("result: "+result);
    Session.set("cdf",result);
    var pqr=Session.get("cdf");
  });
});

我对这种情况下的各种选择做了一些研究,在座的其他一些人可能也已经面临过这种情况

选项A-客户端中的嵌套调用 第一个也是最明显的一个是进行嵌套调用。这意味着在回调中收到结果后调用下一个函数

// level 1
Meteor.call('methodCall', param1, param2, param3, function (error, result) {
    // level 2
    if (error) console.log(error.reason);

    Session.set("xyz",result);

    Meteor.call('methodCall',result, param2, param3, function (error, result) {
        // level 3...
        if (error) console.log(error.reason);

        console.log("result: "+result);
        Session.set("cdf",result);
    }); 

});
优点:经典的js方式,不需要花哨的新概念,服务器方法坚持简单的逻辑,而客户端完成复杂的工作

缺点:丑陋,可能导致混乱,有时难以调试

需要:
Template.autorun
Tracker.autorun
会话
反应性地捕获更改


选项B-包装异步 许多人可能已经发现这种方法是将异步代码构造为同步代码的首选方法

光纤(以及利用光纤的wrapAsync)使代码只看起来是同步的,但执行的性质仍然是异步的。这与承诺工作或异步/等待工作的方式相同

优点:在单一环境中功能强大

缺点:不与Meteor.call一起使用

需要:光纤才能接入

Meteor.call的问题 但是,使用此功能很难调用Meteor方法。考虑下面的代码

const param1 = "param1";
const param2 = "param2";
const param3 = "param3";


const asyncCall = Meteor.wrapAsync(Meteor.call);
const result1 = asyncCall("methodCall", param1, param2, param3);
// result1 will be undefined
为了进一步解释,我将引用:

在客户机上,如果未传递回调且不在 存根,调用将返回未定义,并且您将无法获取 方法的返回值。这是因为客户没有 光纤,所以实际上没有任何方法可以阻止远程通信 方法的执行

概述:
Meteor.wrapAsync
不能与
Meteor.call
一起使用


选项C-一种方法中的束 除了尝试创建meteor调用的同步序列外,还可以向单个服务器方法提供所有参数和逻辑,该方法返回一个保留所有返回值的对象:

client.js

server.js

这将创建一个顺序执行(通过遵循问题中提供的顺序逻辑),并在绑定对象中返回所有结果

优点:按需顺序,一个请求-所有结果 缺点:需要测试的一个额外方法可能会在方法之间引入紧密耦合,返回对象可能会变得庞大而复杂,无法为clinet解析 要求:具有良好的方法设计意识


如果我找到其他选择,我会把它们添加到这篇文章中

您必须使用promise,例如未来光纤

在服务器上

Meteor.methods({
'methodCall': function(params...){
  var future = new Future();
  try{
    your code...
    future.return(result)
  catch(e){
    future.throw(e)
  }finally{
    return future.wait();
  }
 },
})
客户

Meteor.call('methodCall',params...,(err,res)=>{
  if(err){
   console.log(err);
  }else{
   console.log(res);
  }
});
参考链接

Meteor.methods({
'methodCall': function(params...){
  var future = new Future();
  try{
    your code...
    future.return(result)
  catch(e){
    future.throw(e)
  }finally{
    return future.wait();
  }
 },
})
Meteor.call('methodCall',params...,(err,res)=>{
  if(err){
   console.log(err);
  }else{
   console.log(res);
  }
});