我目前正在从Q迁移到Bluebird。
我有以下内容来包装对MongoDB的调用:
DB.prototype.find = function(collectionName /*, query, projection, opt*/){
if (arguments.length < 1) {
return Promise.reject(new _Error("argumentsError", "DB:find expected collection name"));
}
var args = new Array(arguments.length);
args[0] = 'findAsync';
for (var i=1, l=arguments.length; i<l; i++) {
args[i] = arguments[i];
}
var promise = this.getCollection(collectionName);
return promise.call.apply(promise, args);
}
我的问题是,使用Q
,我可以在.post('findAsync', args)
上使用apply
而不是promise.call
。即使这个代码有效,它的很多LOC也只是为了这个。
蓝鸟有更好的方法吗?
答案 0 :(得分:1)
即使这段代码有效,它也只是为了这个。
我不认为很多LOC来自.apply()
声明。它将参数复制到数组中是非常麻烦的,事实上如果使用Q的.post()
方法,你就会拥有完全相同的3行。
如果你真的在乎,你可以将其缩短为
DB.prototype.find = function(collectionName /*, query, projection, opt*/) {
if (!arguments.length)
return Promise.reject(new _Error("argumentsError", "DB:find expected collection name"));
var args = Array.prototype.slice.call(arguments);
args[0] = 'findAsync';
return Promise.prototype.call.apply(this.getCollection(collectionName), args);
}
(虽然这可能有performance implications)。您可能还想尝试一个简单的
arguments[0] = 'findAsync';
return Promise.prototype.call.apply(this.getCollection(collectionName), arguments);
(假设当然是严格模式)。
蓝鸟有更好的方法吗?
我不这么认为。您的代码注释似乎表明您无论如何都期望正好有三个参数,您可能只想让它们成为命名参数并将它们明确地传递给.call()
。
如果您正在寻找一种真正优越的方法,请前往带有休息参数和传播参数的ES6:
DB.prototype.find = function(collectionName, ...args) {
if (!arguments.length)
return Promise.reject(new _Error("argumentsError", "DB:find expected collection name"));
return this.getCollection(collectionName).call('findAsync', ...args);
}