猫鼬承诺和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.resolveq.reject,只需return ret 就足够了。

以上是关于猫鼬承诺和Q承诺的主要内容,如果未能解决你的问题,请参考以下文章

猫鼬和 q 承诺

猫鼬承诺永远不会到达 .then()

猫鼬批量保存承诺

Mongoose.create + Q 将 mongoose 承诺转换为 Q 承诺

猫鼬承诺文档说查询不是承诺?

猫鼬承诺和声纳