使用Bluebird进行Mongoose承诺的正确方法是什么?

Özg*_*sal 10 mongoose bluebird

我一直在阅读文档和文章,每个人似乎都描述了一起使用Mongoose和Bluebird的不同方式.甚至官方的Mongoose文档也说明了一些事情,Bluebird文档说了另一件事.

据Mongoose说:

mongoose.Promise = require('bluebird');
Run Code Online (Sandbox Code Playgroud)

据Bluebird说:

var Promise = require("bluebird");
Promise.promisifyAll(require("mongoose"));
Run Code Online (Sandbox Code Playgroud)

所以据我所知,如果您选择Mongoose方式,示例查询将是:

User.findById('someId')
    .then(function(){
        // do stuff
    })
    .catch(function(err){
        // handle error
    })
Run Code Online (Sandbox Code Playgroud)

但在Mongoose文档中它也说:

Mongoose查询不是承诺.但是,它们对yield和async/await都有.then()函数.如果您需要完全成熟的承诺,请使用.exec()函数.

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

如果你选择Bluebird方式:

User.findById('someId')
    .execAsync()
    .then(function(){
        // do stuff
    })
    .catch(function(err){
        // handle error
    })
Run Code Online (Sandbox Code Playgroud)

或者甚至可以跳过execAsync()并开始findByIdAsync.

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

rob*_*lep 24

选择Mongoose方式:

mongoose.Promise = require('bluebird');
Run Code Online (Sandbox Code Playgroud)

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

Bluebird的promisify*()目的是允许尚未使用promises的代码(纯粹基于回调的函数)返回promise.

  • @MarkStosberg这样做一次应该足够了,只要你在应用程序中尽可能"高涨"(例如app入口点文件,通常称为`app.js`或`server.js`或其他东西). (2认同)

sta*_*las 9

来自Bluebird doc

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
Run Code Online (Sandbox Code Playgroud)

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

var Promise = require("bluebird");
Promise.promisifyAll(require("mongoose"));
Run Code Online (Sandbox Code Playgroud)

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

怎么样mongoose.Promise

然后你使用promise库

mongoose.Promise = require('bluebird');
Run Code Online (Sandbox Code Playgroud)

内置的库代替承诺机制:query.exec().constructor通过更换require('bluebird')所以不是.exec()退货的承诺,你可以直接使用蓝鸟概率猫鼬查询,如

User.findOne({}).then(function(user){
    // ..
})  
Run Code Online (Sandbox Code Playgroud)