【发布时间】:2013-12-12 06:36:11
【问题描述】:
使用 node.js,通过 promises 而不是回调,通过指定用户 id 从 mongo 检索用户对象。数据库访问使用require('mongodb').Db。
调用从以下代码的底部开始:findByIdPromise(userId)collection.findOne() 需要 userId 作为参数,但 then() 调用函数时使用 promise 作为单个参数。
为了绕过这个限制,我传递了then() 一个对象finder,它具有预设的userId 属性,以及一个函数findUser,它接受集合承诺,并调用集合的findOne,将预设的userId 传递给它。
这是一个半体面的方法吗?
UserProvider.prototype.getCollectionPromise = function () {
var deferred = q.defer();
var resolve = deferred.resolve;
var collectionCallback = function (error, usersCollection) {
if (error) {
throw new Error(error);
} else {
resolve(usersCollection);
}
};
this.db.collection(CollectionName, collectionCallback);
return deferred.promise;
};
UserProvider.prototype.findOnePromise = function () {
var userId;
var setUserId = function (id) { this.userId = id; };
var deferred = q.defer();
var resolve = deferred.resolve;
var findUser = function (coll) {
coll.findOne(
{ _id: id },
function(error, result) {
if (error) {
throw new Error(error);
} else {
resolve(result);
}
}
);
};
return deferred.promise;
};
UserProvider.prototype.findByIdPromise = function(id) {
var finder = new UserProvider.findOnePromise();
finder.setUserId(id);
return this.getCollectionPromise().then(finder.findUser);
};
【问题讨论】:
-
“最佳”是非常主观的,因为我不会尝试在 MongoDB API 上分层承诺 API。
-
嗨,WiredPrairie,我不能说我认为帖子的那一行会受到批评。我已将“最佳”更改为“半体面”,以免暗示我认为我的解决方案可能具有出色的竞争力。我是 node、mongo 和 promises 的新手,所以摸不着头脑。为什么不对 Mongo 使用 Promise?
-
@10cls 大多数为节点编写的库都使用回调而不是承诺。据我所见,所有标准库都这样做。您最终将包装几乎所有您想使用的库,以便将其转换为 Promise,这是非常不必要的工作。
-
10cls,代码真的有效吗?我猜这不是出于各种原因,但您的问题被表述为Code Review 而不是“请帮我解决它”。我很困惑。
-
嗨甜菜根,我还没有运行它。我取消了调用此代码的代码,发现我必须使用相同的(反)模式来传递参数。想我应该问这种情况应该如何处理 - (反)模式有效,但我怀疑它在概念上是方形钉,圆孔,或错误,或非惯用,或笨拙,并且需要修复。希望混乱消除。