Pause client sided script on Meteor.call() - wait for Meteor.call()


#1

Okay I have to admit - I am having the same trouble wrapping my head around this sync/async in MeteorJS. I am completely new to Meteor and have no past experience with NodeJS either.

So here’s my case: I am developing a multiplayer game in Meteor and the client side has to halt/wait while the server is handling the database execution. If not, then the user’s will not sync up and have the same data available (ie, if a user kills another user and his script is not halted until that other user is removed from the database, then he would be able to keep killing until the database execution is completed).

My methods are very straight forward:

'killOtherPlayer': function(enemy_id) { 
    PlayersDB.remove({
      _id: enemy_id
    });
}

And I call them simply using

Meteor.call('killOtherPlayer', id);

Now the question is, how do I make the client wait for the server to execute the PlayersDB.remove() function? As it is now, the Meteor.call() functions seem to stack up, but the characters are still able to move around the map while the calls are being executed resulting in loads of calls piling up.

Is Meteor.wrapAsync() the road I need to travel, and if so - how would I approach it?

Thanks a lot!


#2

Look at the docs http://docs.meteor.com/#/full/meteor_call

asyncCallback Function

Optional callback, which is called asynchronously with the error or result after the method is complete. If not provided, the method runs synchronously if possible (see below).

For example:

Meteor.call('killOtherPlayer', id, function (err, res) {
    // do stuff here
})

#3

I am not sure that I am doing it right, but using this Meteor.call() with a callback isn’t working properly:

Meteor.call('killOtherPlayer', id, function (err, res) {
    if(err){
      console.log(err);
    }else{
      console.log('You killed a player');
    }
});

For this particular function it seems to be working (likely because it cannot remove document from the collection several times), but using a collection.update function executes the function several times in a row.

Does the rest of the code execution indeed come to a halt with my Console.log in the callback and my issue lies elsewhere, or am I missing something important here?

EDIT: I am using cursor.observe() to check if something has been removed from the database, something has been changed etc. Could it be due to cursor.observe() not being synced immediately after executing the function?

Double-EDIT: Hmm running the following pseudo code:

Meteor.call('method', var1, var2, function(err, res){
   if(err) {
     console.log(err);
   }else{
     console.log('method output');
   }
});
console.log('output which should execute afterwards');

returns this in the console:

output which should be executed afterwards
method output

Apparently, adding that callback function does not halt execution of the client side at all?

Triple-EDIT: Here’s a MeteorPad showing what I’m talking about: http://meteorpad.com/pad/HPY6SexCZxsB426e8/meteor-call-wait


#4

You mis-read, by adding that callback you made the method call async, if you want it to try and be blocking, you have to call the method without the callback.

Optional callback, which is called asynchronously with the error or result after the method is complete. If not provided, the method runs synchronously if possible (see below).


#5

As far as I know, Javascript code executed in a browser cannot be halted.

To learn more about Javasript callback, google asynchronous callback.


#6

Like @Steve said you have to read more about javascript async callbacks But don’t stop with one article! :smile:

Then you can start to use tools like async or q promises to handle the so called callback hell.

These are not things related to the Meteor platform but you must have good understading about them before using Meteor.

Good luck :wink:


#7

Shouldn’t the killed player be removed on the client side too so they can’t be interacted with?

The client cannot block server executions so you have to use a stub


#8

you made the method call async

I don’t think it was synchronous without the calback to start with


#9

Here, the PlayerDb.remove() call should be made at the client, then there’s no need to halt anything. The client will notify the server who in turn removes the data from the dv and notifies other involved parties.