【问题标题】:mongoose promise and Q promise猫鼬承诺和Q承诺
【发布时间】:2015-05-12 18:18:01
【问题描述】:

[我会回答这个问题,但可以随意添加解决方案或其他可能出现的问题]

在我们大量使用 q promises 和 mongoose 的 nodejs 项目中工作时,我发现了一些将两者结合起来的不直观的小问题。

第一个是猫鼬承诺没有.fail.catch

另一个是Model.create 返回一个promise,它在解析时调用具有多个参数的resolve 函数。如果这通过 Q,那么 Q 将仅使用第一个参数调用解析。

请随意添加更多可能出现的问题;我会将我如何解决这些问题的答案放在答案中。

【问题讨论】:

    标签: javascript node.js mongoose promise 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 就足够了。
    猜你喜欢
    • 2012-12-14
    • 1970-01-01
    • 2019-09-19
    • 2015-10-27
    • 2018-02-15
    • 2017-06-15
    • 2019-06-04
    • 2017-08-18
    • 2019-05-27
    相关资源
    最近更新 更多