2

我有一个目前只支持回调的 Mongoose 插件,我计划可能将它发布到 npmjs,但我首先想确保它像现有的 Mongoose 函数/方法一样工作,它支持回调和一些内置的 Promise,而你也可以指定自己的 promise 库

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

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

另外,对于 Promises,当我返回一个 Promise 时,我应该在传递给插件Promise的对象中使用 thats 吗?Mongoose意义:

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 是如何做到的,但我不太明白如果没有指定回调 PS我使用 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)
    })
4

2 回答 2

0

所以我主要不想依赖特定的承诺库,以防他们使用不同的承诺库,但我意识到在大多数情况下,这并不重要。所以我决定坚持使用 Bluebird,并使用asCallback方法

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

// ./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 聊天)

于 2016-02-05T17:48:50.850 回答
0

就这样做

mongoose.Promise = global.Promise

就如此容易

于 2017-11-15T22:15:16.467 回答