Reputation: 10429
My client is making a call to the server.
Meteor.call('someRequest', params, onAllDoneCallback);
that is processed by (server code)
Meteor.methods({
'someRequest': function(params, cb) {
anAsyncFunction(params, cb);
return true;
},
});
I'd like the onAllDoneCallback
to be triggered on the client side once the anAsyncFunction
has finished and triggers its own callback.
However, in Meteor it seems that the second argument of someRequest
is ignored and that the onAllDoneCallback
is triggered with what someRequest
returns, which here is true
and which is called before that anAsyncFunction
has finished.
In my case I'm more concerned about the timing issue (I'm using it to tell the client that the processing is finished, and not just that the request is well received) but other will probably want to call the callback with arguments from anAsyncFunction
Upvotes: 5
Views: 2959
Reputation: 10429
adapting this answer: Meteor: Proper use of Meteor.wrapAsync on server
You have to use Meteor
's wrapAsync
api, which takes a function that accepts a callback as its last argument, the callback being like function(error, result){}
. So it will look like:
Meteor.methods({
'someRequest': function(params){
var wrap = Meteor.wrapAsync(anAsyncFunction);
return wrap(params);
},
});
Upvotes: 0
Reputation: 11197
What you are doing now is passing a function to the server. If that does work, it's very insecure. What you want to do is create a future and then use it to manage the asynchronous function. Here is an example:
let Future = Npm.require('fibers/future');
Meteor.methods({
someRequest: function (someArg) {
// for security reasons, make sure you check the type of arguments.
check(someArg, String);
// future is an async handler.
let future = new Future();
// this is a function for a generic node style callback [ie, function (err, res)]
let resolver = future.resolver();
// run your function and pass it the future resolver
// the future will be resolved when the callback happens.
anAsyncFunction(someArg, resolver);
// this meteor method will not end until future has been resolved.
return future.wait();
}
});
Alternatively, Meteor provides a wrapAsync
that provides similar functionality of wrapping async functions in futures so they can run in meteor methods. That is:
let wrappedAsyncFunction = Meteor.wrapAsync(anAsyncFunction /** second argument is `this` binding*/);
return wrappedAsyncFunction();
Upvotes: 4