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

Jos*_*ura 39 javascript meteor

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

(怎么样)可能吗?

Meteor.methods({
  my_function: function(arg1, arg2) {
    //Call other asynchronous function and return result or throw error
  }
});
Run Code Online (Sandbox Code Playgroud)

Jos*_*cha 36

使用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();
  }
});
Run Code Online (Sandbox Code Playgroud)

更新:

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

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

  // use Future here
});
Run Code Online (Sandbox Code Playgroud)

  更新2:

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

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

  // use Future here
});
Run Code Online (Sandbox Code Playgroud)

然后使用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();
  }
});
Run Code Online (Sandbox Code Playgroud)

看到这个要点.


And*_*Mao 26

最新版本的Meteor提供了未记录的Meteor._wrapAsync函数,它将带有标准(err, res)回调的函数转换为同步函数,这意味着当前的光纤会在回调返回之前产生,然后使用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     
  }
});
Run Code Online (Sandbox Code Playgroud)

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

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

  • 截至0.9.3 _wrapAsync已被弃用,转而使用wrapAsync https://github.com/meteor/meteor/blob/50e6d3143db8fc6e1fc3fb74da74b40c8dc7f3a4/packages/meteor/helpers.js#L153 (5认同)

小智 19

安德鲁毛泽东是对的.对于这种情况,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

        });
    }
});
Run Code Online (Sandbox Code Playgroud)

我发现这篇文章非常有用: Meteor:在服务器上正确使用Meteor.wrapAsync

  • 如果你在回调中返回一个值来收费()那将是收费()的回报吗? (2认同)
  • 不清楚你在哪里返回一个值,这是原始问题的重点 (2认同)
  • 这篇文章非常有用:https://themeteorchef.com/snippets/synchronous-methods/ (2认同)

Ful*_*ack 5

另一个选择是这个实现了类似的目标.

meteor add meteorhacks:async
Run Code Online (Sandbox Code Playgroud)

从包README:

Async.wrap(功能)

包装异步函数并允许它在没有回调的情况下在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;
  }
});
Run Code Online (Sandbox Code Playgroud)