猫鼬承诺和Q承诺
Posted
技术标签:
【中文标题】猫鼬承诺和Q承诺【英文标题】:mongoose promise and Q promise 【发布时间】:2015-05-12 18:18:01 【问题描述】:[我会回答这个问题,但可以随意添加解决方案或其他可能出现的问题]
在我们大量使用 q promises 和 mongoose 的 nodejs 项目中工作时,我发现了一些将两者结合起来的不直观的小问题。
第一个是猫鼬承诺没有.fail
或.catch
。
另一个是Model.create 返回一个promise,它在解析时调用具有多个参数的resolve 函数。如果这通过 Q,那么 Q 将仅使用第一个参数调用解析。
请随意添加更多可能出现的问题;我会将我如何解决这些问题的答案放在答案中。
【问题讨论】:
【参考方案1】:您可以简单地使用 Q
function 将 Mongoose 承诺转换为“正确的”Q 承诺 - 这实际上适用于每个 thenable。
所以只需使用
Q(someMongoosePromise) .then(…).catch(…);
Multiple arguments 是一个不同的问题。但是,有一个非常简单的技巧:将它们转换为数组并使用它。
Q(Model.create([doc1,doc2]).then(Array)) .spread(function(d1, d2) … );
(此解决方案不适用于Model.create
返回单个数字的承诺)
【讨论】:
mongoose 指定替代承诺库的能力怎么样。mongoose.Promise = require('q').Promise;
@Jaime 是的,这是个好主意。不知道为什么我没有提到它,也许 2 年前 Q 或 mongoose 都不支持它。【参考方案2】:
因为 mongoose 承诺没有 .catch
或 .fail
(请注意,q 也会从他们的库中删除它们)您不能在结束的 aq 堆栈上返回失败的 mongoose 承诺使用 .catch 或 .fail 而不先将其转换为 aq 承诺。这是我的做法(这在堆栈的其他地方也得到了回答):
function something()
return q()//make sure this function returns a promise instead of an unhandled error
.then(function()
//do some stuff
)
.then(function()
return someMongoosePromise
.then(function resolve(res)//make sure to return a q promise if this function is called in a stack that has
//.then.then.then(function()return something();).fail(...
return q.resolve(res);
,function reject(err)
return q.reject(err);
);
);
我遇到的第二个问题是 Model.create([doc1,doc2]) 用多个参数解决了 Promise,但是当通过 q q 时只用一个参数调用 resolve:
q()
.then(function()
return Model.create([doc1,doc2]);
)
.then(function(docs)
docs===doc1;//David Copperfield took doc2
);
解决方法和第一个差不多:
q()
.then(function()
return Model.create([doc1,doc2])
.then(function()//let mongoose resolve the promise
var ret=[],i=arguments.length;
while(--i>-1)
ret.push(arguments[i];
return q.resolve(ret);
);
)
.then(function(docs)
docs===[doc1,doc2];
);
【讨论】:
你的第二个解决方案doesn't actually work @Bergi 我明天看看,可能是复制粘贴错误 糟糕,请忽略该评论。它看起来太像延迟的反模式,抱歉。但实际上你根本不需要在那里使用q.resolve
和q.reject
,只需return ret
就足够了。以上是关于猫鼬承诺和Q承诺的主要内容,如果未能解决你的问题,请参考以下文章