Javascript Meteor:在 Meteor.method 中调用异步函数并返回结果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12569712/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Meteor: Calling an asynchronous function inside a Meteor.method and returning the result
提问by Joseph Tura
I want to call an asynchronous function inside a Meteor method and then return the result from that function to Meteor.call.
我想在 Meteor 方法中调用一个异步函数,然后将该函数的结果返回给 Meteor.call。
(How) is that possible?
(如何)这可能吗?
Meteor.methods({
my_function: function(arg1, arg2) {
//Call other asynchronous function and return result or throw error
}
});
采纳答案by Hymansonkernion
Andrew Mao is right. Meteor now has Meteor.wrapAsync()for this kind of situation.
安德鲁毛是对的。Meteor 现在有Meteor.wrapAsync()用于这种情况。
Here's the simplest way to do a charge via stripe and also pass a callback function:
这是通过条带进行充电并传递回调函数的最简单方法:
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
});
}
});
I found this post really helpful: Meteor: Proper use of Meteor.wrapAsync on server
我发现这篇文章真的很有帮助: Meteor:在服务器上正确使用 Meteor.wrapAsync
回答by Joscha
Use a Future to do so. Like this:
使用 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();
}
});
Update:
更新:
To use Future starting from Meteor 0.5.1, you have to run the following code in your Meteor.startup method:
要从 Meteor 0.5.1 开始使用 Future,您必须在 Meteor.startup 方法中运行以下代码:
Meteor.startup(function () {
var require = __meteor_bootstrap__.require
Future = require('fibers/future');
// use Future here
});
Update 2:
更新2:
To use Future starting from Meteor 0.6, you have to run the following code in your Meteor.startup method:
要从 Meteor 0.6 开始使用 Future,您必须在 Meteor.startup 方法中运行以下代码:
Meteor.startup(function () {
Future = Npm.require('fibers/future');
// use Future here
});
and then use the return
method instead of the ret
method:
然后使用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();
}
});
See this gist.
看到这个要点。
回答by Andrew Mao
Recent versions of Meteor have provided the undocumented Meteor._wrapAsync
function which turns a function with a standard (err, res)
callback into a synchronous function, meaning that the current Fiber yields until the callback returns, and then uses Meteor.bindEnvironment to ensure that you retain the current Meteor environment variables (such as Meteor.userId())
.
最新版本的 Meteor 提供了未公开的Meteor._wrapAsync
函数,该函数将带有标准(err, res)
回调的函数转换为同步函数,这意味着当前 Fiber 会产生直到回调返回,然后使用 Meteor.bindEnvironment 来确保您保留当前的 Meteor 环境变量(比如Meteor.userId())
.
A simple use would be as the following:
一个简单的用法如下:
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
}
});
You may also need to use function#bind
to make sure that asyncFunc
is called with the right context before wrapping it.
您可能还需要使用function#bind
来确保asyncFunc
在包装它之前使用正确的上下文调用它。
For more information see: https://www.eventedmind.com/tracks/feed-archive/meteor-meteor-wrapasync
有关更多信息,请参阅:https: //www.eventedmind.com/tracks/feed-archive/meteor-meteor-wrapasync
回答by FullStack
Another option is this packagewhich achieves the similar goals.
另一种选择是这个包,它实现了类似的目标。
meteor add meteorhacks:async
From the package README:
从包自述文件:
Async.wrap(function)
异步包装(函数)
Wrap an asynchronous function and allow it to be run inside Meteor without callbacks.
包装一个异步函数并允许它在没有回调的情况下在 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;
}
});