I have good news smile: and bad news
The good news: my experimentation with Promises in Meteor methods shows:
- If you use the inbuilt
ecmascript
Promises (including async/await
, they seem to play very nicely with Meteor.
- If you want to use Bluebird, and you promisify the async versions of any of Meteor’s sync-style (fiber) methods, along with any other async methods you’re using, then you can avoid that irksome fiber stuff and it works. The fundamental issue with Bluebird if you also need to use Meteor’s sync-style stuff “as-is” is that the resolve and reject callbacks need to be wrapped in fibers - and that’s a pain.
So, using the ecmascript
Promises, you can, for example, define your code like:
async function doSomething() {
const res0 = await somePromisedAsyncFunction();
const res1 = await anotherPromisedAsyncFunction(res0);
return res1;
}
Meteor.methods({
doSomethingFirst() {
return doSomething();
},
fetchFromServiceA() {
// my business logic
return new Promise(...);
},
writeOrUpdatedB(res) {
// my business logic
return new Promise(...);
},
});
And they will all resolve as expected when called from the client.
The bad news: they don’t resolve as expected when called from the server, so this doesn’t work correctly:
async function doSomething() {
const res0 = await callAsync('fetchFromServiceA');
const res1 = await callAsync('writeOrUpdatedB', res0);
return res1;
}
Meteor.methods({
doSomethingFirst() {
return doSomething();
},
fetchFromServiceA() {
// my business logic
return new Promise(...);
},
writeOrUpdatedB(res) {
// my business logic
return new Promise(...);
},
});
What seems to happen is that instead of getting a result (resolved Promise), the actual Promise is returned as the result. I’ve not fully bottomed this out yet, but it looks like it may be a bug - perhaps @benjamn could comment? Note, I haven’t tried a server-to-server call, only a “within-server” call.
In any event, although methods are supposed to be callable “within-server”, the guide recommends using direct function calls (probably just for performance reasons).
Note that you should only use a Method in the case where some code needs to be callable from the client; if you just want to modularize code that is only going to be called from the server, use a regular JavaScript function, not a Method.
So, as long as you’re prepared to move method logic into separately callable functions for server use, you should be good to go (I haven’t got round to testing that either).