In document
I don’t understand how a stub can be executed synchronously.
Can you please describe it with an example ?
In document
I don’t understand how a stub can be executed synchronously.
Can you please describe it with an example ?
@jamgold Thank you for the demo! But, I still have 2 questions.
How can I get the return value of stub?
And I don’t understand the meaning of “The client has no problem executing a stub synchronously” in document. Can you please suggest an example or description of that?
That’s because it’s not doing a RPC. It’s just running client side code, which can be run syncronously.
@babrahams So, do you mean that a stub is always executing synchronously(because they are just simulating the result of the real server method), even if the real server side method is executing asynchronously ?
Yes, I’m pretty sure that’s what’s happening. Not sure how you get the return value from a stub though, as the result from the callback (function(error, result) { ... }
) is the return value from the real server side execution.
Oh Thank you so much @babrahams.
Now I understand almost! Can I ask you one more question?
If I assume that I invoke the real server side method named B with callback in another real server side method named A with callback, are both A and B executed asynchronously ?? and are the stub of A and stub of B executed synchronously ??
That’s my understanding, based on what is found in the docs and my own experiments. The stub of B will be executed syncronously within the context of the callback, which is fired after a server round-trip. So stub of B is not entirely syncronous.
client.js
console.log('start');
Meteor.call('a', function(err,res) {
console.log('Result of a:', res);
Meteor.call('b', function(e,r) {
console.log('Result of b:',r);
});
console.log('After b is called. Have we seen the result of b yet?');
});
console.log('finish');
common.js
Meteor.methods({
a: function() {
return 'A';
},
b: function() {
return 'B';
}
});
The above code produces this in the client console:
"start" app.js:1:12
"finish" app.js:9:0
"Result of a:" "A" app.js:3:2
"After b is called. Have we seen the result of b yet?" app.js:7:2
"Result of b:" "B"
Meteorpad example is here if you want to play around with it.
client.js
console.log(‘start’);
for (i = 0; i < 10; i++) {
Meteor.call(‘a’, i, function (err, res) {
console.log(‘Result of a:’, res);
Meteor.call(‘b’, i, function (e, r) {
console.log(‘Result of b:’, r);
});
console.log(‘After b is called. Have we seen the result of b yet?’);
});
}
console.log(‘finish’);
public.js
Meteor.methods({
a: function (x) {
// stub
if(this.isSimulation) {
console.log('isSimulation - A : ’ + x);
return 'A-stub : ’ + x;
// Server side method
} else {
// When it is server, delay a while.
for (i=0; i < 10000000; i++){}
return 'A : ’ + x;
}
} ,
b: function (x) {
// stub
if(this.isSimulation) {
console.log('isSimulation - B : ’ + x);
return 'B-stub : ’ + x;
// Server side method
} else {
// When it is server, delay a while.
for (i=0; i < 10000000; i++){}
return 'B : ’ + x;
}
}
});
result for browser console
start
finish
Result of a: A : 0
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 1
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 2
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 3
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 4
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 5
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 6
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 7
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 8
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 9
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of b: B : 10
Interesting test. That last line:
… was that, by any chance, repeated 10 times in the console? If so, it all makes a bit more sense.
The result of
is expected because by the time the first callback of method a
is run on the client (i.e. after a server round trip), the value of i
is already 10 and method b
is only called from within callbacks of method a
.
I have to admit, I’m not sure why isSimulation
isn’t set to true
on the client side run of method a
. In fact, it seems that method a
isn’t even being run on the client. I expected it would for latency compensation purposes. I’d be interested to hear if anyone knows why this is the case.
Also I found out that it is working well(logging “isSimulation - A” on console) when Meteor.methods is divided into server block and client block, even though “isSimulation - A” is not working when used with “this.isSimulation” or “Meteor.isClient” on public block(when write once for both server and client).
(Actually, I’m seriously curious of why this is working, and the others are not… )
You can check the following code working well.
Code
if (Meteor.isClient) {
Meteor.methods({
a: function (x) {
// stub
console.log('isSimulation - A : ' + x);
return 'A-stub : ' + x;
},
b: function (x) {
// stub
console.log('isSimulation - B : ' + x);
return 'B-stub : ' + x;
}
});
console.log('start');
for (i = 0; i < 10; i++) {
Meteor.call('a', i, function (err, res) {
console.log('Result of a:', res);
Meteor.call('b', i, function (e, r) {
console.log('Result of b:', r);
});
console.log('After b is called. Have we seen the result of b yet?');
});
}
console.log('finish');
}
if (Meteor.isServer) {
Meteor.methods({
a: function (x) {
// When it is server, delay a while.
for (i = 0; i < 10000000; i++) {}
return 'A : ' + x;
},
b: function (x) {
// When it is server, delay a while.
for (i = 0; i < 10000000; i++) {}
return 'B : ' + x;
}
});
}
Result
start
isSimulation - A : 0
isSimulation - A : 1
isSimulation - A : 2
isSimulation - A : 3
isSimulation - A : 4
isSimulation - A : 5
isSimulation - A : 6
isSimulation - A : 7
isSimulation - A : 8
isSimulation - A : 9
finish
Result of a: A : 0
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 1
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 2
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 3
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 4
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 5
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 6
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 7
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 8
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of a: A : 9
isSimulation - B : 10
After b is called. Have we seen the result of b yet?
Result of b: B : 10
Result of b: B : 10
Result of b: B : 10
Result of b: B : 10
Result of b: B : 10
Result of b: B : 10
Result of b: B : 10
Result of b: B : 10
Result of b: B : 10
Result of b: B : 10
</blockquote>
In the client, the function inside Method ‘a’ wasn’t exist at the moment you call it, therefore, your last example works, but the previous one doesn’t, because you swapped their sequence. I’ve modified your code and fixed the scope issue in [here][1]. (PS: there is something weird happened in passing a scope variable to the second call ‘b’, and it requires to declare and assign a local var to fix that )
[1]: http://meteorpad.com/pad/i4PpiqenqTbJm94zK/Copy%20of%20Methods%20syncronicity%20test