使用可选参数和 运行 多次承诺回调样式

Promisify callback style with optional arguments and run multiple times

我正在尝试 Promisify 使用 bluebird 这个函数,它有一个可选的第二个参数(权重),但我不知道我是只尝试执行方法还是整个对象。

  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 本身的问题而无法完全理解。谢谢!

有点难看出你想做什么,但这里有一个想法,显示了一个手动 promisified 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,但这应该让您大致了解什么你正在努力实现。

如果 .incr() 方法已经有效(特别是如果它是您要合并到项目中的第三方库的一部分),您最好的选择可能是保持原样,并为 promise 版本创建一个单独的方法,在这种情况下它相当容易:

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