I am attempting to created a throttling function. I have looked at a few SO posts and copied some code but I am unable to get it to delay.
Basically I have a number of methods in a class that need to call the Amazon API. They all make use of a common function - doCall
which I implemented as follows:
Amazon.prototype.doCall = function(func) {
var self = this;
var queue = P.resolve();
function throttle(fn) {
var res = queue.then(function() { // wait for queue
return fn(); // call the function
});
queue = P.delay(61000).return(queue); // make the queue wait for 61 seconds
return res; // return the result
}
// Create instance of MWS client
if (!this.client) {
this.client = new mws.Client(key, secret, merchant, {});
}
var call = function() {
// The library uses a weird signature so I am wrapping it thus
return new P(function(resolve, reject) {
// The original MWS library call
self.client.invoke(func, function(r, e) {
// ... stuff
resolve(r);
});
});
};
return throttle(call);
};
Basically I fetch order lists and orders and need to delay each call 60+ seconds. Right now it all happens without a delay whatsoever. Suggestions?
I am basically using it like this (contrived but should give the idea)
self.doCall(ListOrders).then(function(res) {
// parse results
self.doCall(ListMoreOrdersByPage).then(function(res) {
// Now I might go through each and fetch details
var ids = [...] // Parse result for ids
return P.map(ids, function(id) {
return doCall(GetOrderById);
});
....
Your problem is that
Amazon.prototype.doCall = function(func) { var queue = P.resolve(); …
means that you are re-creating a new queue
on every call of that method. Not really helpful. Instead you probably want one queue per Amazon
instead, so put the initialisation in the constructor.
I've also simplified your code a bit:
function Amazon(…) {
…
this.queue = P.resolve();
}
Amazon.prototype.doCall = function(func) {
if (!this.client) {
// Create instance of MWS client
this.client = new mws.Client(key, secret, merchant, {});
}
var self = this;
var res = this.queue.then(function() {
// The library uses a weird signature so I am wrapping it thus
return new P(function(resolve, reject) {
self.client.invoke(func, function(r, e) {
// ... stuff
resolve(r);
});
});
});
this.queue = this.queue.delay(610000); // make the queue wait for 61s
// if you want to make it wait *between* calls, use
// this.queue = res.catch(function(){}).delay(610000);
return res;
};