【问题标题】:What is the correct way of using Bluebird for Mongoose promises?将 Bluebird 用于 Mongoose 承诺的正确方法是什么?
【发布时间】:2017-03-25 21:28:33
【问题描述】:

我一直在阅读文档和文章,每个人似乎都以不同的方式描述了一起使用 Mongoose 和 Bluebird 的方式。甚至官方的 Mongoose 文档 says something 和 Bluebird 文档都说 another thing

根据猫鼬:

mongoose.Promise = require('bluebird');

根据蓝鸟:

var Promise = require("bluebird");
Promise.promisifyAll(require("mongoose"));

因此,据我了解,如果您选择 Mongoose 方式,示例查询将如下所示:

User.findById('someId')
    .then(function(){
        // do stuff
    })
    .catch(function(err){
        // handle error
    })

但在 Mongoose 文档中也是这样说的:

Mongoose 查询不是承诺。但是,它们确实有一个用于 yield 和 async/await 的 .then() 函数。如果您需要一个成熟的承诺,请使用 .exec() 函数。

那么在这种情况下,.then 是否高于承诺?

如果你选择蓝鸟方式:

User.findById('someId')
    .execAsync()
    .then(function(){
        // do stuff
    })
    .catch(function(err){
        // handle error
    })

或者甚至可以跳过execAsync() 并以findByIdAsync 开头。

真的与不同的文档混淆了。如果有人能对此有所了解,我将不胜感激。

【问题讨论】:

    标签: mongoose bluebird


    【解决方案1】:

    选择猫鼬方式:

    mongoose.Promise = require('bluebird');
    

    那是因为 Mongoose已经支持 Promise(除了接受回调);上面的代码只是用 Bluebird 替换了 Mongoose 自己的 Promise 库 (mpromise)(它可能更快,测试更好,并且有更多的实用功能可用)。

    Bluebird 的promisify*() 旨在允许未已经使用承诺(纯粹基于回调的函数)的代码返回承诺。

    【讨论】:

    • 感谢您的回答。这改善了@stasovlas 的回答。
    • mongoose 可能会被加载并在代码库中的许多地方建立连接。哪些位置需要mongoose.Promise = require('bluebird');?我相信 Mongoose 对象是一个单例对象,但我很难让这个更改在一个大型项目中生效。
    • @MarkStosberg 做一次就足够了,只要你在你的应用程序中尽可能“高”地做它(比如应用程序入口点文件,通常称为app.jsserver.js什么的)。
    • 当我这样做时,我得到"[ts] Cannot assign to 'Promise' because it is a constant or a read-only property."
    【解决方案2】:

    来自 Bluebird 文档

    Promise.promisifyAll(
        Object target,
        [Object {
            suffix: String="Async",
            multiArgs: boolean=false,
            filter: boolean function(String name, function func, Object target, boolean passesDefaultFilter),
            promisifier: function(function originalFunction, function defaultPromisifier)
        } options] ) -> Object
    

    如你所见,默认情况下,promisifyAll 添加后缀'Asyns',所以如果你使用这种方式的promisification:

    var Promise = require("bluebird");
    Promise.promisifyAll(require("mongoose"));
    

    User.findById 的异步版本将是 User.findByIdAsync

    mongoose.Promise 怎么样

    然后你使用像

    这样的 Promise 库
    mongoose.Promise = require('bluebird');
    

    内置的 promise 机制被库替换:query.exec().constructorrequire('bluebird') 替换所以而不是 .exec() 用于返回 promise,您可以直接使用蓝鸟概率进行猫鼬查询,如

    User.findOne({}).then(function(user){
        // ..
    })  
    

    【讨论】:

    • 感谢您的回答。如果我走猫鼬的方式怎么样?正如我在我的问题中所问的那样,.then 在这种情况下是否是一个承诺?是否有理由选择一种方式而不是另一种方式?
    【解决方案3】:

    对于那些使用 TypeScript 的人来说,正确的方法是:

    (<any>mongoose).Promise = YOUR_PROMISE;

    来自文档:

    Typescript does not allow assigning properties of imported modules. To avoid compile errors use one of the options below in your code:
    
    (<any>mongoose).Promise = YOUR_PROMISE;
    
    require('mongoose').Promise = YOUR_PROMISE;
    
    import mongoose = require('mongoose'); mongoose.Promise = YOUR_PROMISE;
    

    【讨论】:

      猜你喜欢
      • 2015-11-25
      • 2017-10-09
      • 1970-01-01
      • 1970-01-01
      • 2017-08-06
      • 2016-03-01
      • 2018-09-21
      • 2015-09-26
      • 2015-03-14
      相关资源
      最近更新 更多