创建支持回调和承诺

时间:2016-02-05 06:44:12

标签: node.js mongoose bluebird es6-promise mongoose-plugins

我有一个目前只支持回调的Mongoose插件,我打算将它发布到npmjs,但我首先要确保它的工作方式与现有的Mongoose函数/方法一样,它们支持回调和{{3} },你也可以some built in promises

我想知道在我的库中实现相同功能的最佳方法是什么,这意味着我如何支持回调承诺?我找到了specify your own promise library,但这是蓝鸟特有的,即使我喜欢使用它,我也不想假设它会被使用。 (此外,该文章看起来可能已过时,因为我在a similar SO thread

中找不到nodeify

我在想我可以做一些基本逻辑来查看函数是否作为参数之一提供,如果是,则执行回调,如果没有,则返回一个承诺...但我确定这样更容易这样做的方法。

另外,对于Promises,当我返回一个promise时,我应该使用传递给插件的Promise对象里面的Mongoose那个吗?含义:

module.exports = Mongoose => {
    // Just verifying, should I use this?..
    const Promise = Mongoose.Promise

    return Mongoose.model( 'Foobar', new Mongoose.Schema({ /* ... */ }) )
}

更新

关于最后一个问题,关于Promise对象在返回promises时要引用的内容,我尝试使用上面提到的Mongoose.Promise,代码如下:

module.exports = Mongoose => {
    const Promise = Mongoose.Promise
    const Schema = Mongoose.Schema

    const fooSchema = new Schema({
        name: Schema.Types.String
    })

    fooSchema.statics.blah = function( ) {
        // Return Mongoose.Promise
        return new Promise( ( res, rej ) => {
            res( 'test' )
        })
    }

    return Mongoose.model( 'Foobar', fooSchema )
}

...导致错误:

/Users/me/project/node_modules/mongoose/lib/ES6Promise.js:21
  throw 'Can\'t use ES6 promise with mpromise style constructor';
  ^
Can't use ES6 promise with mpromise style constructor

所以我猜这不是正确的方法......我认为使用Mongoose配置的相同承诺库(自定义或默认值)返回promises会更好。

我试着通过查看bluebird api docs函数代码来了解Mongoose是如何做到的,但如果没有指定回调,我也不会看到它如何返回一个promise P.S。我正在使用Mongoose 4.3.7

更新

只是在修补,但这是一种可接受的方法吗?或者这是不好的做法

function tester(foo, cb){
    return new Promise( ( res, rej ) => {
        const result = 'You said ' + foo
        if( typeof cb === 'function' ){
            cb( null, result )
            res() // Is this needed?
        }
        else {
            res( result )
        }
    })
}

tester('foo', (err, data) => {
    if( err )
        console.log('ERROR!',err)
    else
        console.log('Result:',data)
})

tester('bar')
    .then( data => {
        console.log('Result:',data)
    })
    .catch( err => {
        console.log('ERROR!',err)
    })

2 个答案:

答案 0 :(得分:0)

所以我主要不想依赖特定的诺言库,因为他们使用的是另一个,但我意识到,在大多数情况下,它并不重要。所以我决定坚持使用Bluebird,并使用 asCallback 方法

下面是最终结果,这是我编写一个具有支持回调和承诺的函数的库;并且在一个单独的文件中,不需要特定的promise库,使用该函数两次,一次使用promise,一次使用回调:

// ./test-lib.js
'use strict'

const Promise = require( 'bluebird' )

module.exports = ( str, cb ) => {
    const endResult = ( txt ) => new Promise( ( res, rej ) => res( 'You said ' + txt ) )
    return endResult( str ).asCallback( cb );
}

// app.js
'use strict'

const Testlib = require('./test-lib')

Testlib('foo', ( err, data ) => {
    if( err )
        console.error('ERROR:',err)
    else
        console.log('DATA:',data)
})

Testlib('bar')
    .then( data => {
        console.log('DATA:',data)
    })
    .catch( err => {
        console.error('ERROR:',err)
    })

// Result:
// DATA: You said foo
// DATA: You said bar

这似乎完美无缺! (感谢Bluebird Gitter的tyscorp聊天)

答案 1 :(得分:0)

就这样做

mongoose.Promise = global.Promise

就像那个一样简单