Different results of callAsync and applyAsync

Hi. Please consider a simple async method. Its stub returns different value than the server execution.

Meteor.methods({
    async test() {
        if (Meteor.isServer) {
            return false;
        } else {
            return true;
        }
    }
});

Then, in client code, I call this method with callAsync and applyAsync.

async callTheTest() {
      const resultCall = await Meteor.callAsync('test');
      const resultApply = await Meteor.applyAsync('test');
      console.log(resultCall, resultApply); // false, true
}

The first seems to resolve correctly to the server value, but the latter resolves immediately to the stub value and ignores the fact that the server later responded differently. Why?

Meteor v2.8.1.

I know this topic is a bit stale but I’m also having trouble understanding applyAsync.

From what I’ve learned the value Meteor.applyAsync returns is the promise as returned by the stub. If you want to get to the value returned by the server you still have to use the callback which is weird as we’re talking about an async function here.

From my tests, I also noticed applyAsync will keep the server-side method running for much longer than callAsync, which immediately returns the promise for you to work with/wait for.
This gets in the way of the recommendations made here Migrating to Meteor 2.8 | Meteor Guide where it is suggested to wait for your async methods before firing the second method call in order to not make the client think it is a stub for the first call when it should actually fire off the second method to the server as well.

As a follow-up, if you look at the source for callAsync, you’ll notice that it actually does some extra DDP magic to indicate that the method is still running or not. This allows subsequent methods to run in their own context instead of thinking they are a stub for the first applyAsync call.