web-dev-qa-db-ja.com

Meteor:Meteor.method内で非同期関数を呼び出し、結果を返す

Meteorメソッド内で非同期関数を呼び出し、その関数から結果をMeteor.callに返したい。

(そんなことがあるものか?

Meteor.methods({
  my_function: function(arg1, arg2) {
    //Call other asynchronous function and return result or throw error
  }
});
39
Joseph Tura

アンドリュー・マオは正しい。 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.wrapAsyncの適切な使用

19
jacksonkernion

そのためには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();
  }
});

this Gist を参照してください。

36
Joscha

Meteorの最近のバージョンでは、標準の_Meteor._wrapAsync_コールバックを持つ関数を同期関数に変換する文書化されていない_(err, res)_関数が提供されています。つまり、現在のFiberは、現在の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     
  }
});
_

ラップする前に、asyncFuncが正しいコンテキストで呼び出されることを確認するために、_function#bind_を使用する必要がある場合もあります。

詳細については、以下を参照してください: https://www.eventedmind.com/tracks/feed-archive/meteor-meteor-wrapasync

26
Andrew Mao

別のオプションはこれです package これは同様の目標を達成します。

meteor add meteorhacks:async

パッケージのREADMEから:

Async.wrap(function)

非同期関数をラップし、コールバックなしで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;
  }
});
5
FullStack