Meteor:在 Meteor.method 中调用异步函数并返回结果

IT技术 javascript meteor
2021-01-28 10:02:53

我想在 Meteor 方法中调用一个异步函数,然后将该函数的结果返回给 Meteor.call。

(如何)这可能吗?

Meteor.methods({
  my_function: function(arg1, arg2) {
    //Call other asynchronous function and return result or throw error
  }
});
4个回答

使用 Future 来做到这一点。像这样:

Meteor.methods({
  my_function: function(arg1, arg2) {

    // Set up a future
    var fut = new Future();

    // This should work for any async method
    setTimeout(function() {

      // Return the results
      fut.ret(message + " (delayed for 3 seconds)");

    }, 3 * 1000);

    // Wait for async to finish before returning
    // the result
    return fut.wait();
  }
});

更新

要从 Meteor 0.5.1 开始使用 Future,您必须在 Meteor.startup 方法中运行以下代码:

Meteor.startup(function () {
  var require = __meteor_bootstrap__.require
  Future = require('fibers/future');

  // use Future here
});

  更新2

要从 Meteor 0.6 开始使用 Future,您必须在 Meteor.startup 方法中运行以下代码:

Meteor.startup(function () {
  Future = Npm.require('fibers/future');

  // use Future here
});

然后使用return方法而不是ret方法:

Meteor.methods({
  my_function: function(arg1, arg2) {

    // Set up a future
    var fut = new Future();

    // This should work for any async method
    setTimeout(function() {

      // Return the results
      fut['return'](message + " (delayed for 3 seconds)");

    }, 3 * 1000);

    // Wait for async to finish before returning
    // the result
    return fut.wait();
  }
});

看到这个要点

谢谢你,乔沙。未来正是我所需要的。
2021-03-22 10:02:53
从 0.6.0 开始,您必须使用Future = Npm.require('fibers/future').
2021-03-25 10:02:53
@KONG,我更新了我的答案,见上文。我还分叉了最初的要点以包含该信息:gist.github.com/4130605
2021-03-30 10:02:53
这是一个完整的工作演示:github.com/semateos/meteor-async-test
2021-04-01 10:02:53
@Joscha,非常感谢您的解决方案!我设法自己谷歌。Future是这样一个包的通用名称:)
2021-04-03 10:02:53

最新版本的 Meteor 提供了未公开的Meteor._wrapAsync函数,该函数将具有标准(err, res)回调的函数转换为同步函数,这意味着当前 Fiber 会产生直到回调返回,然后使用 Meteor.bindEnvironment 来确保您保留当前的 ​​Meteor 环境变量(比如Meteor.userId())

一个简单的用法如下:

asyncFunc = function(arg1, arg2, callback) {
  // callback has the form function (err, res) {}

};

Meteor.methods({
  "callFunc": function() {
     syncFunc = Meteor._wrapAsync(asyncFunc);

     res = syncFunc("foo", "bar"); // Errors will be thrown     
  }
});

您可能还需要使用function#bind来确保asyncFunc在包装它之前使用正确的上下文调用它。

有关更多信息,请参阅:https : //www.eventedmind.com/tracks/feed-archive/meteor-meteor-wrapasync

从 0.9.3 开始,_wrapAsync 已被弃用,取而代之的是 wrapAsync github.com/meteor/meteor/blob/...
2021-03-27 10:02:53

安德鲁毛是对的。Meteor 现在有Meteor.wrapAsync()用于这种情况。

这是通过条带进行充电并传递回调函数的最简单方法:

var stripe = StripeAPI("key");    
Meteor.methods({

    yourMethod: function(callArg) {

        var charge = Meteor.wrapAsync(stripe.charges.create, stripe.charges);
        charge({
            amount: amount,
            currency: "usd",
            //I passed the stripe token in callArg
            card: callArg.stripeToken,
        }, function(err, charge) {
            if (err && err.type === 'StripeCardError') {
              // The card has been declined
              throw new Meteor.Error("stripe-charge-error", err.message);
            }

            //Insert your 'on success' code here

        });
    }
});

我发现这篇文章真的很有帮助: Meteor:在服务器上正确使用 Meteor.wrapAsync

如果在charge() 的回调中返回一个值,那会是charge() 的返回值吗?
2021-03-30 10:02:53
2021-04-01 10:02:53
不清楚你在哪里返回一个值,这是原始问题的重点
2021-04-10 10:02:53

另一种选择是这个,它实现了类似的目标。

meteor add meteorhacks:async

从包自述文件:

异步包装(函数)

包装一个异步函数并允许它在没有回调的情况下在 Meteor 中运行。

//declare a simple async function
function delayedMessge(delay, message, callback) {
  setTimeout(function() {
    callback(null, message);
  }, delay);
}

//wrapping
var wrappedDelayedMessage = Async.wrap(delayedMessge);

//usage
Meteor.methods({
  'delayedEcho': function(message) {
    var response = wrappedDelayedMessage(500, message);
    return response;
  }
});