【问题标题】:Creating a Mongoose plugin that supports callbacks AND promises创建一个支持回调和承诺的 Mongoose 插件
【发布时间】:2016-05-15 01:24:18
【问题描述】:

我有一个 Mongoose 插件,目前只支持回调,我计划可能将它发布到 npmjs,但我首先想确保它像现有的 Mongoose 函数/方法一样工作,支持回调和some built in promises,你也可以specify your own promise library

我想知道在我的库中实现相同功能的最佳方式是什么,这意味着我如何同时支持回调 承诺?我找到了a similar SO thread,但那是蓝鸟特有的,尽管我喜欢使用它,但我不想假设它会被使用。 (另外,那篇文章看起来可能已经过时了,因为我在bluebird api docs 中找不到nodeify

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

另外,对于 Promise,当我确实返回一个 Promise 时,我是否应该使用传递给插件的 Mongoose 对象内的 Promise ?含义:

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

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

更新

关于最后一个问题,关于返回 Promise 时要引用什么 Promise 对象,我尝试使用如上所述的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 配置的相同承诺库(自定义或默认......)返回承诺会更好。

我试图通过查看 findOne 函数代码来了解 Mongoose 是如何做到的,但是如果没有指定回调,我不太明白它是如何返回承诺的 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)
    })

【问题讨论】:

  • 我不知道你为什么还要尝试创建一个猫鼬插件......芒果已经支持插件不是它......为什么它需要一个插件......?你要创建像猫鼬但不是猫鼬的东西......?!
  • 我正在尝试创建一个 mongoose 插件...您认为我正在尝试创建一个插件系统或其他东西吗?...我只是在问如何创建一个 mongoose 插件,支持回调 承诺,就像 Mongoose 本身一样

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


【解决方案1】:

就这样吧

mongoose.Promise = global.Promise

就这么简单

【讨论】:

    【解决方案2】:

    所以我主要不想依赖特定的 Promise 库,以防他们使用不同的,但我意识到在大多数情况下,这并不重要。所以我决定坚持使用 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
    

    这似乎工作得很好! (感谢tyscorpBluebird Gitter 聊天)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-23
      • 2015-11-27
      • 2020-12-05
      • 2013-05-20
      • 1970-01-01
      • 2015-06-05
      • 2016-06-15
      • 1970-01-01
      相关资源
      最近更新 更多