Mongoose with Bluebird promisifyAll – 对模型对象的saveAsync结果作为已解决的承诺值

我用蓝猫的promisifyAll与mongoose。 当我在模型对象上调用saveAsync(保存的promisified版本)时,完成的promise的parsing值是一个包含两个元素数组。 第一个是我保存的模型对象,第二个是整数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()方法返回一个单独的对象,所以我期待这个数组中的第一个项目。

任何帮助将不胜感激!

警告:这种行为改变了蓝鸟3 – 在蓝鸟3问题中的默认代码将工作,除非一个特殊的参数将传递给promisifyAll。


.save的callback的签名是:

  function (err, product, numberAffected) 

由于这不遵守返回一个值的节点callback约定,蓝鸟将多值响应转换为一个数组。 数字代表受影响的项目数量(如果在数据库中find并更新了文档,则为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"); }) 

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

 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