Создание плагина Mongoose, который поддерживает обратные вызовы и обещания

У меня есть плагин Mongoose, который в настоящее время поддерживает только обратные вызовы, я планирую, возможно, опубликовать его в npmjs, но сначала я хотел убедиться, что он работает так же, как существующие функции/методы Mongoose, которые поддерживают обратные вызовы и некоторые встроенные промисы, а также вы можете указать собственную библиотеку промисов.

Я хотел знать, как лучше всего реализовать ту же функциональность в моей библиотеке, то есть как я могу поддерживать как обратные вызовы , так и обещания? Я нашел похожий поток SO, но это специфично для bluebird, который, хотя мне нравится использовать, я не хотел бы предполагать, что он будет использоваться. (Кроме того, эта статья выглядит устаревшей, так как я не смог найти nodeify в bluebird документы API

Я думал, что могу просто выполнить некоторую базовую логику, чтобы увидеть, была ли функция предоставлена ​​​​в качестве одного из параметров, если да, то выполнить обратный вызов, если нет, то вернуть обещание... но я уверен, что есть более простой способ сделать это.

Кроме того, для промисов, когда я делаю возвращаю промис, должен ли я использовать Promise внутри объекта Mongoose, переданного плагинам? Имея в виду:

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

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

Обновлять

Что касается последнего вопроса, о том, на какой объект 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 (Custom или по умолчанию..)

Я попытался увидеть, как это делает Mongoose, посмотрев на код функции findOne, но я не совсем понимаю, как она возвращает обещание, если не указан обратный вызов 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)
    })

person Justin    schedule 05.02.2016    source источник
comment
Я не уверен, почему вы вообще пытаетесь создать плагин для мангуста... мангус уже поддерживает плагины, не так ли... Зачем ему плагин? Вы собираетесь создать что-то вроде мангуста, но не мангуста..?!   -  person T J    schedule 05.02.2016
comment
Я пытаюсь создать плагин мангуста... Вы думаете, я пытаюсь создать систему плагинов или что-то в этом роде?.. Я просто спрашиваю, как мне создать плагин мангуста, который поддерживает как обратные вызовы , так и обещает, как это делает сам Mongoose   -  person Justin    schedule 05.02.2016


Ответы (2)


просто сделай это

mongoose.Promise = global.Promise

так просто, как, что

person Jalasem    schedule 15.11.2017

Поэтому я в основном не хотел полагаться на конкретную библиотеку промисов, если они использовали другую, но я понял, что по большей части это не должно иметь большого значения. Поэтому я решил придерживаться 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)

person Justin    schedule 05.02.2016