在不调用'then'的情况下parsingPromise

我有这个代码是我为一个名为Poolio的NPM模块写的一个小API的一部分。 对于那些支持错误优先callback以及承诺的人来说,我所遇到的问题似乎是一个常见问题,我们如何在维护API和来自API的一致返回值的同时支持这两个问题? 例如,如果我有条件地从我的API返回一个承诺,取决于我的lib的消费者是否提供callback,在我看来这有点尴尬。

lib的用户可以提供callback或使用Promisefunction,但不能同时使用。

这是我的lib导出的函数,我想promisify:

Pool.prototype.any = function (msg, cb) { var workId = this.counter++; var self = this; return new Promise(function (resolve, reject) { if (typeof cb === 'function') { self.resolutions.push({ workId: workId, cb: cb }); } else { self.resolutions.push({ workId: workId, resolve: resolve, reject: reject }); } if (this.available.length > 0) { var cp = this.available.shift(); cp.workId = workId; cp.send(msg); } else { self.msgQueue.push({ workId: workId, msg: msg }); } }); }; 

我的问题是 – 如果用户在原始函数参数中提供了callback函数,那么如何在不调用“then”的情况下解决promise? 对不起,这很难解释,但希望你能理解。

也有这个有趣的问题: 永不解决的承诺导致内存泄漏?

这其实很简单。 只有你可能错过了它,因为它隐藏在代码的纠结之中。

基本上你这样做:

 var promise = new Promise(function (resolve, reject) { /*....*/}); if (typeof cb === 'function') { promise.then(cb); } else { return promise; } 

实际上,这是一个很常见的API( mongodb-driver example )。 基本上,编写一个接受callback的私有函数,编写一个公共函数检查cb,并在必要时编写它。 使用你的github代码( _any可能需要重构,你不需要检查cb是否是一个函数,也可能是其他的东西):

  // private function var _any = function(msg, cb) { if (this.kill) { console.log('warning: pool.any called on pool of dead/dying workers'); return; } debug('current available pool size for pool_id ' + this.pool_id + ' is: ' + this.available.length); var workId = this.counter++; if (typeof cb === 'function') { this.resolutions.push({ workId: workId, cb: cb }); } else { workId = -1; } if (this.available.length > 0) { var cp = this.available.shift(); cp.workId = workId; cp.send(msg); } else { this.msgQueue.push({ workId: workId, msg: msg }); } }; // public exposed function Pool.prototype.any = function(msg, cb) { if (typeof cb === 'function') { // cb is provided, no action is required here return _any(msg, cb); } // no cb, wrap the call inside a Promise and provide a cb return new Promise(function(resolve, reject) { _any(msg, function(err, data) { if (err) reject(err); else resolve(data); }); }); }