使用可选参数Promisify回调样式并多次运行

时间:2017-01-08 15:07:12

标签: javascript node.js promise bluebird

我正在尝试使用bluebird这个具有可选第二个参数(权重)的函数Promisify而且我只是不知道我是否只尝试方法或整个对象。

  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));
  };

原文在这里(https://github.com/dudleycarr/ratelimit.js/blob/master/src/rate_limit.coffee),但coffeescript因此认为这个编译版本更具普遍性。

我认为需要定制promisify?

另外,我的最终目标是在回归测试套件中进行此调用,并且能够使用相同的键和权重调用参数运行可配置的次数,并从我的最终回调中获取每个回调的结果数组回调。

类似的东西:

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);
}));

我已经尝试过Array()。fill()。map和Promises.map的组合,但是由于初始Promisify本身的问题而无法完全得到它。谢谢!

2 个答案:

答案 0 :(得分:0)

很难看出你正在尝试做什么,但是这里有一个想法,表明了一个受到约束的incr()Promise.map()的使用通过一系列值运行它:

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);
});

我不能说我会详细了解您的.incr()功能正在尝试做什么或如何转换为直接的Javascript,但这应该让您大致了解您所做的事情。重新尝试实现。

答案 1 :(得分:0)

如果.incr()方法已经有效(特别是如果它是你所加入项目的第三方库的一部分),你最好的选择可能就是保持原样,并创建承诺版本的单独方法,在这种情况下它很容易:

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));
    });
};

使用它:

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);
    }));