问题
I'm trying to use this NPM package: Gumroad-API inside my Meteor app. I'm encountering issues on the server side when I try to do a Meteor method call (or a collection insert) inside of the Promise callback.
The following is the code for my two Meteor methods:
Meteor.methods({
testMethod: () => {
console.log('TEST METHOD RUN');
},
fetchGumroadData: () => {
const Gumroad = Meteor.npmRequire('gumroad-api');
let gumroad = new Gumroad({ token: Meteor.settings.gumroadAccessKey });
Meteor.call('testMethod'); // runs fine
gumroad.listSales('2014-12-04', '2099-12-04', 1).then((result) => {
console.log('1'); // runs fine
Meteor.call('testMethod'); // execution halts here w/o error msg
console.log('2'); // this never runs
});
},
});
The code inside the .then() callback always halts (without error msgs) whenever I try to do a Meteor.call() inside of it.
I get the same behaviour when I replace the Meteor.call() with a Collection.insert() such as: Sales.insert({text:'test'});.
回答1:
Old question but, the reason this fails is because the Meteor environment is not available in your callback.
caveat this is untested code
Meteor.methods({
testMethod: () => {
console.log('TEST METHOD RUN');
},
fetchGumroadData: () => {
const Gumroad = Meteor.npmRequire('gumroad-api');
let gumroad = new Gumroad({ token: Meteor.settings.gumroadAccessKey });
Meteor.call('testMethod'); // runs fine
gumroad.listSales('2014-12-04', '2099-12-04', 1)
.then(Meteor.bindEnvironment((result) => {
console.log('1'); // runs fine
Meteor.call('testMethod'); // execution halts here w/o error msg
console.log('2'); // this never runs
}));
},
});
Tutorials on bindEnvironment and wrapAsync can be found here: https://www.eventedmind.com/items/meteor-what-is-meteor-bindenvironment
回答2:
I don't use promises much, so I don't know why you are seeing that error. When using external APIs like that i typically use wrapAsync so I can write my code in a synchronous fashion but still achieve the same results.
In your case that would look something like this:
Meteor.methods({
testMethod: () => {
console.log('TEST METHOD RUN');
},
fetchGumroadData: () => {
const Gumroad = Meteor.npmRequire('gumroad-api');
let gumroad = new Gumroad({ token: Meteor.settings.gumroadAccessKey });
Meteor.call('testMethod'); // runs fine
let wrappedListSales = Meteor.wrapAsync(gumroad.listSales, gumroad);
let result = wrappedListSales('2014-12-04', '2099-12-04', 1);
console.log('1');
Meteor.call('testMethod');
console.log('2');
},
});
The second argument to Meteor.wrapAsync is optional and may not be needed, depending on the nature of the gumroad API
回答3:
I ended up ditching the NPM package and writing my own API call. I could never figure out how to make my call inside the .then(). Here's the code:
fetchGumroadData: () => {
let options = {
data: {
access_token: Meteor.settings.gumroadAccessKey,
before: '2099-12-04',
after: '2014-12-04',
page: 1,
}
};
HTTP.call('GET', 'https://api.gumroad.com/v2/sales', options, (err,res) => {
if (err) { // API call failed
console.log(err);
throw err;
} else { // API call successful
Meteor.call('testMethod');
}
});
}
来源:https://stackoverflow.com/questions/34377304/calling-a-meteor-method-inside-a-promise-callback-halting-w-o-error