Mongoose с Bluebird promisifyAll - saveAsync на объекте модели приводит к массиву как разрешенному значению обещания

Я использую bluebird promisifyAll с мангустом. Когда я называю saveAsync (обещанную версию сохранения) на объекте модели, разрешенное значение завершенного обещания представляет собой массив с двумя элементами. Первый - мой сохраненный объект модели, второй - целое число 1. Не уверен, что происходит здесь. Ниже приведен пример кода для воспроизведения проблемы.

var mongoose = require("mongoose");

var Promise = require("bluebird");


Promise.promisifyAll(mongoose);


var PersonSchema = mongoose.Schema({
    'name': String
});

var Person = mongoose.model('Person', PersonSchema);

mongoose.connect('mongodb://localhost/testmongoose');


var person = new Person({ name: "Joe Smith "});

person.saveAsync()
.then(function(savedPerson) {
    //savedPerson will be an array.  
    //The first element is the saved instance of person
    //The second element is the number 1
    console.log(JSON.stringify(savedPerson));
})
.catch(function(err) {
    console.log("There was an error");
})

Ответ, который я получаю,

[{"__v":0,"name":"Joe Smith ","_id":"5412338e201a0e1af750cf6f"},1]

Я ожидал только первый элемент в этом массиве, так как метод save() модели mongoose возвращает один объект.

Любая помощь будет принята с благодарностью!

Ответ 1

Предупреждение: Это поведение меняется как синяя птица 3 - в bluebird 3 код по умолчанию в вопросе будет работать, если специальный аргумент не будет передан promisifyAll.


Подпись .save обратного вызова:

 function (err, product, numberAffected)

Так как это не соответствует соглашению об обратном вызове node для возврата одного значения, bluebird преобразует многозначный ответ в массив. Число представляет количество произведенных элементов (1, если документ был найден и обновлен в БД).

Вы можете получить синтаксический сахар с .spread:

person.saveAsync()
.spread(function(savedPerson, numAffected) {
    //savedPerson will be the person
    //you may omit the second argument if you don't care about it
    console.log(JSON.stringify(savedPerson));
})
.catch(function(err) {
    console.log("There was an error");
})

Ответ 2

Почему бы просто не использовать встроенную поддержку обещаний мангуста?

var mongoose = require('mongoose');
var Promise = require('bluebird');

mongoose.Promise = Promise;
mongoose.connect('mongodb://localhost:27017/<db>');

var User = require('./models/user');
User.findOne({}).then(function(user){
    // ..
});

Подробнее об этом: http://mongoosejs.com/docs/promises.html