我有这个代码,它是我为一个名为Poolio的NPM模块编写的小API的一部分。对于那些支持错误优先回调和承诺的人来说,我的问题似乎是一个常见的问题 - 我们如何在维护API的一致API和一致的返回值的同时支持这两个问题?例如,如果我有条件地从我的API返回一个promise,取决于我的lib的使用者是否提供回调,我认为这有点尴尬。
lib的使用者可以提供回调或使用Promise then函数,但不能同时使用。
这是我的lib导出的函数,我想宣传:
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
});
}
});
};
我的问题是 - 如果用户在原始函数参数中提供回调函数,如何在不调用'然后'?的情况下解析承诺。 对不起,很难解释,但希望你能理解。
答案 0 :(得分:2)
实际上非常简单。只有你可能错过了它,因为它隐藏在那些混乱的代码中。
基本上你这样做:
var promise = new Promise(function (resolve, reject) { /*....*/});
if (typeof cb === 'function') {
promise.then(cb);
} else {
return promise;
}
答案 1 :(得分:1)
实际上,API做的很常见(mongodb-driver example)。基本上,编写一个接受回调的私有函数,编写一个检查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);
});
});
}