javascript - 如何在javascript中等待 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.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()将不会成功执行,因为第一个参数不会有任何值,因为步骤3在步骤2之前执行。那么有什么方法可以实现这一点并等待 meteor 调用完成来执行下一条指令?

最佳答案

我对这种情况的各种选择进行了一些研究,因为这里的其他一些人可能也已经面临过这种情况。

选项 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.autorunTracker.autorun 响应式(Reactive)捕获 Session 中的更改。


选项 B - 包裹异步

许多人可能已经发现此方法是将异步代码构造为同步代码的第一选择。

纤维(以及利用纤维的wrapAsync)使代码仅看起来是同步的,但执行的本质仍然是异步的。这与 Promises 工作或 async/await 工作方式相同。

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

缺点:不能与 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

为了进一步解释,我将引用 documentation :

On the client, if you do not pass a callback and you are not inside a stub, call will return undefined, and you will have no way to get the return value of the method. That is because the client doesn’t have fibers, so there is not actually any way it can block on the remote execution of a method.

摘要:Meteor.wrapAsync 不能与 Meteor.call 一起使用。


选项 C - 以一种方法捆绑

您还可以向单个服务器方法提供所有参数和逻辑,而不是尝试创建同步的 meteor 调用序列,该方法返回一个保留所有返回值的对象:

client.js

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


Meteor.call('methodCall', param1, param2, param3, function (err, result) {
  const xyz = result.xyz;
  const cdf = result.cdf;
});

server.js

function _methodCall(p1, p2, p3) {
  // ... 
  return result;
}

Meteor.methods({
  'methodCall'(p1, p2, p3) {
    const result1 = _methodCall(p1, p2, p3);
    const result2 = _methodCall(result1, p2, p3);
    return {
      xyz: result1,
      cdf: result2,
    }
  }
})

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

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

如果我找到其他选项,我会将它们添加到这篇文章中。

关于javascript - 如何在javascript中等待 meteor 调用响应然后执行其他语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49391469/

相关文章:

javascript - 运行 angular.js 作为回调(例如 $.ajax)

javascript - 创建一个保留顺序的 javascript 哈希表?

javascript - js如何让一个变量值根据用户登录 Node 存在

javascript - meteor 包加载顺序

javascript - 警报在 html 加载之前执行

javascript - 我如何将 CSS 类传递给 React 子项并确保它们将覆盖子项的本地类?

javascript - 使用 .jsx 扩展名测试 React 组件

node.js - Redis pub/sub - 同一进程监听一个 channel

javascript - MongoDB - 如果对象包含小于 x 的值,如何删除数组中的对象?

javascript - 如何确定我在 Meteor 中进行 OAuth 重新身份验证的 session ?