0

I have several function calls in a row that run and wait to return, then the next one runs. After these are run I have one function I want to run, but then I don't want to wait for it to be done before I run my return.

Here is an example of what I mean.

get_card, create_order, create_association and debit_order all need to wait for the previous function to complete before they can run. When I get to Queue.start_account_creation_task I want it to start running, but then let the return on the line below run right away too.

Meteor.methods({
    singleDonation: function (data) {
        logger.info("Started singleDonation");

                //Get the card data from balanced and store it
                var card = Utils.get_card(customerData._id, data.paymentInformation.href);

                //Create a new order
                var orders = Utils.create_order(data._id, customerData.href);

                //Associate the card with the balanced customer
                var associate = Utils.create_association(customerData._id, card.href, customerData.href);

                //Debit the order
                var debitOrder = Utils.debit_order(data.paymentInformation.total_amount, data._id, customerData._id, orders.href, card.href);

            Queue.start_account_creation_task(customerData._id, data._id, debitOrder._id);
            return {c: customerData._id, don: data._id, deb: debitOrder._id};
    }
});
JoshJoe
  • 1,482
  • 2
  • 17
  • 35
  • https://meteorhacks.com/fibers-eventloop-and-meteor.html – sdooo Feb 10 '15 at 18:13
  • @Sindis Can you give me a hint here? I've looked at this article and I don't see how I could use this. Mostly it is talking about doing the opposite of what I'm trying to accomplish. – JoshJoe Feb 10 '15 at 20:49
  • Try wrapping all actions that need to wait for each other into one fiber – sdooo Feb 10 '15 at 21:54
  • @Sindis I need to return to the client before the last function is completed. I don't think wrapping in a fiber will do since I need to wait for all of the previous work to complete before starting the last function. – JoshJoe Feb 10 '15 at 21:58
  • Maybe you can try callbacks in every function. If it wont work I can't help you further – sdooo Feb 10 '15 at 22:08
  • @Sindis. This won't work. Thanks for the help. – JoshJoe Feb 11 '15 at 03:21

2 Answers2

0

Sounds like you need parallel and serial control for tasks. The (as in, 400,000 downloads a day) Node.js module for that is called async, and a Meteor wrapper for it is peerlibrary:async.

Sooner or later you'll need a dedicated background task management package. If async is insufficient, have a look at my evaluation of packages to control background tasks in Meteor.

Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
  • I was actually able to solve my problem by using this. Meteor.setTimeout(function(){ Utils.create_user(customerData._id, data._id, debitOrder._id); }, 100); – JoshJoe Feb 11 '15 at 15:12
  • I really need to learn more about what is going on here, but I think the reason this works is that the task is both async and meteor takes care of the bindEnvironment so that I still get all of my variable references passed to it. Does that sound about right? – JoshJoe Feb 11 '15 at 15:14
  • setTimeout didn't work for me because the function I call uses Fibers / Future. The async module works and feels less hacky. – Little Brain Jun 11 '20 at 11:46
0

The thing that seemed to work the best for what I was trying to do was to just use a Meteor.setTimeout({}). It might seem like an odd choice, but it does everything I needed, including setting the Meteor Environment so that I didn't have to do any BindEnrironment call. It also breaks out of the current thread of calls, which means it then returns the result to the client and a second later finishes the rest of the calls (which are to external APIs that I didn't need my users sitting there waiting for).

JoshJoe
  • 1,482
  • 2
  • 17
  • 35