创build一个支持callback和承诺的Mongoose插件

我有一个Mongoose插件,目前只支持callback,我打算将其发布到npmjs,但我首先想确保它的工作方式就像现有的Mongoose函数/方法,它支持callback函数和一些内置的promise ,而你也可以指定你自己的承诺库 。

我想知道在我的库中实现相同function的最好方法是什么,这意味着我怎样才能同时支持callback承诺? 我发现了一个类似的SO线程 ,但这是特定于蓝鸟,即使我喜欢使用,Id喜欢不承担它将被使用。 (另外,这篇文章看起来可能会过时,因为我nodeifybluebird API文档中findnodeify

我想我可以只是做一些基本的逻辑,看看是否提供了一个函数作为参数之一,如果是的话,然后执行callback,如果没有,然后返回一个承诺…但我确定这是一个更简单的方法来做那。

此外,对于承诺,当我做出承诺的时候,我应该使用那些交给插件的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 

所以我猜这不是正确的方式去…我认为这是一个更好的主意,使用相同的承诺库Mongooseconfiguration(自定义,或默认..)

我试图通过查看findOne函数代码来了解Mongoose是如何实现的,但是我不太清楚它如何返回一个promise如果没有指定PS Im使用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) }) 

       

网上收集的解决方案 "创build一个支持callback和承诺的Mongoose插件"

就这样做

 mongoose.Promise = global.Promise 

就如此容易

所以我主要不想依赖一个具体的承诺库,因为他们使用的是另外一个库,但是我意识到,大部分情况下它并不重要。 所以我决定坚持使用Bluebird,并使用asCallback方法

下面是最终的结果,这是与我一个函数,支持callback和承诺编码一个图书馆; 并在一个单独的文件,而不需要一个特定的承诺库,使用该function两次,一次承诺,一次callback:

 // ./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 

这似乎是完美的工作! (感谢tyscorp Bluebird Gitter聊天)