【问题标题】:Meteor, chaining method callsMeteor,链接方法调用
【发布时间】:2017-01-21 00:49:05
【问题描述】:

我有一个尝试操作数据库的 Meteor 方法,如果成功,则调用一个异步方法。我希望能够调用此方法并返回异步调用的结果或数据库操作的错误。

这是(大致)我在服务器上的代码:

Meteor.methods({
    'data.update'(id, data) {
        Collection.update({id_: id}, {$set: {data: data}}, error => {
            if (error) {
                // Have method return Meteor error for DB-failure
            } else {
                callAsync(id, (error, res) => {
                    if (error) {
                        // Have method return Meteor error for async call failure
                    } else {
                        // Have method return success(res)
                    }
                })
            }
        })
    }
});

我已阅读有关 Futures 和 Promises 的内容,但我对这些概念很陌生,我不确定何时使用什么。最好我正在寻找一种不依赖于 Meteor/ES6 之外的任何第三方库的解决方案。奖励(相关)问题:数据库操作后通常会返回什么,让我将回调附加到方法?

【问题讨论】:

  • 期货和承诺没有区别(除了术语)?尽管在 JS 中我们称它们为“承诺”,是的,您应该返回一个。
  • 正如我所说,我对这些概念很陌生。我知道在 Scala 中它们是不同但相关的概念,维基百科说“Futures 和 Promise 起源于函数式编程和相关范式(例如逻辑编程),以将值(未来)与其计算方式(承诺)解耦”。 JS 中的 future 和 promise 之间的一大区别是你只能对后者进行有意义的谷歌搜索;)。
  • 是的,terminology 在 JS 中有点奇怪。我们谈论的是 deferred 和 promise 而不是 promise 和 future,而且无论如何,deferred 正被逐步淘汰,取而代之的是纯回调。
  • 我明白了:)。无论如何,如果你对在这种情况下我应该如何使用 Promise 有一个很好的答案,请随时写一个答案,我会接受它。
  • 我不太了解meteor,所以这里恐怕帮不了你。

标签: javascript meteor ecmascript-6


【解决方案1】:

根据docs

在服务器上,如果您不提供回调,则更新块 直到数据库确认写入,或者抛出异常,如果 有些不对劲。如果您确实提供了回调,则更新返回 立即地。更新完成后,将使用回调调用 失败情况下的单个错误参数,或第二个参数 如果更新是,则表明受影响的文档数量 成功。

因此,如果update 成功,则返回受影响的文档数。如果是insert,则返回插入文档的_id

如前所述,您可以简单地将第三个参数传递给更新函数。

对于 promise 的实现,你可以使用Meteor.wrapAsync 方法。如果您还需要传递实例变量的状态,您可能还想查看Meteor.bindEnvironment 来实现这一点。

【讨论】:

    【解决方案2】:

    您可以考虑使用 Promises,但在 Meteor 生态系统中还有另一种相当标准的方式来处理此类事情。您可以使用Meteor.wrapAsync 将基于异步回调的函数转换为基于Fibers 的版本。然后,这将让您利用返回值和异常。这是一个简单的例子:

    1) 假设我们在某处有一个名为 increaseLifetimeWidgetCount 的内部函数,它增加了数据库中某处的生命周期小部件计数,然后调用带有错误或新更新的生命周期计数的回调:

    function increaseLifetimeWidgetCount(callback) {
      // ...
      // increase the lifetime widget count in the DB somewhere, and 
      // get back the updated widget count, or an error.
      // ...
      const fakeError = null;
      const fakeLifetimeWidgetCount = 1000;
      return callback(fakeError, fakeLifetimeWidgetCount);
    }
    

    2) 假设我们定义了一个简单的方法,它将在我们的数据库中创建一个新的小部件,调用我们内部的increaseLifetimeWidgetCount 函数,然后返回新更新的生命周期小部件计数。由于我们想要返回更新后的生命周期小部件计数,我们将基于回调的 increaseLifetimeWidgetCount 函数包装在 Meteor.wrapAsync 调用中,并返回结果:

    Meteor.methods({
      newWidget(data) {
        check(data, Object);
        Widgets.insert(data);
        const increaseLifetimeWidgetCountFiber =
          Meteor.wrapAsync(increaseLifetimeWidgetCount);
        const lifetimeWidgetCount = increaseLifetimeWidgetCountFiber();
        return lifetimeWidgetCount;
      }
    });
    

    3) 然后我们可以通过异步回调从客户端调用newWidget 方法,并处理返回的错误或返回的生命周期小部件计数:

    Meteor.call('newWidget', { 
      name: 'Test Widget 1' 
    }, (error, result) => { 
      // Do something with the error or lifetime widget count result ...
      console.log(error, result);
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多