I'm trying to Promisify with bluebird this function that has an optional second argument (weight) and it's just not working out whether I try to the do just the method or the whole object.
RateLimit.prototype.incr = function(keys, weight, callback) {
var args, err, _ref, _ref1;
if (arguments.length === 2) {
_ref = [1, weight], weight = _ref[0], callback = _ref[1];
}
try {
_ref1 = this.scriptArgs(keys, weight), keys = _ref1[0], args = _ref1[1];
} catch (_error) {
err = _error;
return callback(err);
}
return this["eval"].exec(this.checkIncrFn, keys, args, (function(_this) {
return function(err, result) {
return callback(err, __indexOf.call(_this.constructor.DENIED_NUMS, result) >= 0);
};
})(this));
};
Original is here ( https://github.com/dudleycarr/ratelimit.js/blob/master/src/rate_limit.coffee ) but coffeescript so figured this compiled version is a bit more universally readable.
I think a custom promisify would be needed?
Also, my end goal is to have this call in a regression test suite and be able to be run a configurable amount of times with the same keys and weight calling parameters and get an array of the results from each callback in my final callback.
something like this:
var runTimes = 5;
var runKey = ‘akey’;
var runWeight = 2;
var keyMap = Array(5).fill(runKey);
Promise.all(Promise.map(keyMap, (k, w) => pPromisifiedIncr(k, w))
.then((values) => {
console.log(values);
}));
I've tried combinations of Array().fill().map and Promises.map but was unable to quite get it possibly due to issues with the initial Promisify itself. Thanks!
It's a little hard to see what you're trying to do, but here's an idea that shows a manaully promisified incr()
and a use of Promise.map()
to run it through an array of values:
RateLimit.prototype.incr: function(keys, weight, callback) {
return new Promise((resolve, reject) => {
let args;
// callback argument is optional
if (arguments.length === 2) {
callback = weight;
weight = 1;
}
// if this throws, it will automatically reject the promise
[keys, args] = this.scriptArgs(keys, weight);
this["eval"].exec(this.checkIncrFn.bind(this), keys, args, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result.indexOf(this.constructor.DENIED_NUMS) > 0);
}
});
});
}
var keys = [{weight: 1, key: 'akey1'}, {weight: 2, key: 'akey2'}, {weight: 3, key: 'akey3'}, {weight: 4, key: 'akey4'}];
Promise.map(keys, item => xxx.incr(item.key, item.weight)).then((values) => {
console.log(values);
});
I can't say I follow all the details of what your .incr()
function is trying to do or how it translates to straight Javascript, but this should give you a general idea of what you're trying to achieve.
If the .incr()
method already works (and especially if it's part of a third party library that you're incorporating into your project), your best option would probably be to leave it the way it is, and create a separate method for the the promise version, in which case it's rather easy:
RateLimit.prototype.incrPromise = function(keys, weight) {
var self = this;
var args = arguments;
return new Promise(function (resolve, reject) {
var callback = function (err, result) {
if(err) { reject(err); } else { resolve(result); }
};
self.incr.apply(self, Array.prototype.concat.call(args, callback));
});
};
To use it:
var runTimes = 5;
var runKey = ‘akey’;
var runWeight = 2;
var keyMap = Array(5).fill(runKey);
var myRateLimit = new RateLimit(); // create RateLimit here
Promise.all(Promise.map(keyMap, (k, w) => myRateLimit.incrPromise(k, w))
.then((values) => {
console.log(values);
}));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.