Je veux appeler une fonction asynchrone dans une méthode Meteor, puis renvoyer le résultat de cette fonction à Meteor.call.
(Comment est-ce possible?
Meteor.methods({
my_function: function(arg1, arg2) {
//Call other asynchronous function and return result or throw error
}
});
Andrew Mao a raison. Meteor a maintenant Meteor.wrapAsync () pour ce genre de situation.
Voici le moyen le plus simple de facturer via stripe et également de passer une fonction de rappel:
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
});
}
});
J'ai trouvé cet article vraiment utile: Meteor: bon usage de Meteor.wrapAsync sur le serveur
Utilisez un avenir pour le faire. Comme ça:
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();
}
});
Mise à jour :
Pour utiliser Future à partir de Meteor 0.5.1, vous devez exécuter le code suivant dans votre méthode Meteor.startup:
Meteor.startup(function () {
var require = __meteor_bootstrap__.require
Future = require('fibers/future');
// use Future here
});
Mise à jour 2 :
Pour utiliser Future à partir de Meteor 0.6, vous devez exécuter le code suivant dans votre méthode Meteor.startup:
Meteor.startup(function () {
Future = Npm.require('fibers/future');
// use Future here
});
puis utilisez la méthode return
au lieu de la méthode 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();
}
});
Voir ce Gist .
Les versions récentes de Meteor ont fourni la fonction Meteor._wrapAsync
Non documentée qui transforme une fonction avec un rappel standard (err, res)
En une fonction synchrone, ce qui signifie que la fibre actuelle cède jusqu'à ce que le rappel revienne, puis utilise Meteor. bindEnvironment pour vous assurer de conserver les variables d'environnement Meteor actuelles (telles que Meteor.userId())
.
Une utilisation simple serait la suivante:
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
}
});
Vous devrez peut-être également utiliser function#bind
Pour vous assurer que asyncFunc
est appelé avec le bon contexte avant de l'encapsuler.
Pour plus d'informations, voir: https://www.eventedmind.com/tracks/feed-archive/meteor-meteor-wrapasync
Une autre option est ceci package qui atteint les mêmes objectifs.
meteor add meteorhacks:async
À partir du package README:
Async.wrap (fonction)
Enveloppez une fonction asynchrone et autorisez-la à s'exécuter à l'intérieur de Meteor sans rappel.
//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;
}
});