使用Bluebird的Mongoose promisifyAll - 在模型对象上的saveAsync导致Array作为已解析的promise值

时间:2014-09-11 23:54:33

标签: node.js mongoose promise bluebird

我正在使用蓝鸟的promisifyAll和猫鼬。当我在模型对象上调用saveAsync(保存的promisified版本)时,已完成的promise的解析值是一个带有两个元素的数组。第一个是我保存的模型对象,第二个是整数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]

我只期待该数组中的第一项,因为mongoose模型save()方法返回单个对象。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:30)

警告:此行为更改为bluebird 3 - 在bluebird 3中,除非将特殊参数传递给promisifyAll,否则问题中的默认代码将起作用。


.save回调的签名是:

 function (err, product, numberAffected)

由于这不遵守返回一个值的节点回调约定,因此bluebird将多值响应转换为数组。数字表示受影响的项目数(如果在DB中找到并更新了文档,则为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");
})

答案 1 :(得分:13)

为什么不只使用mongoose的内置承诺支持?

const mongoose = require('mongoose')
const Promise = require('bluebird')

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

const UserModel = require('./models/user')
const user = await UserModel.findOne({})
// ..

了解更多信息: http://mongoosejs.com/docs/promises.html