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

win*_*ith 10 mongoose node.js promise bluebird

我正在使用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");
})
Run Code Online (Sandbox Code Playgroud)

我得到的回应是

[{"__v":0,"name":"Joe Smith ","_id":"5412338e201a0e1af750cf6f"},1]
Run Code Online (Sandbox Code Playgroud)

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

任何帮助将不胜感激!

Ben*_*aum 30

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


.save回调的签名是:

 function (err, product, numberAffected)
Run Code Online (Sandbox Code Playgroud)

由于这不遵守返回一个值的节点回调约定,因此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");
})
Run Code Online (Sandbox Code Playgroud)

  • D'哦!我应该正确阅读mongoose文档!谢谢! (3认同)

rck*_*ckd 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({})
// ..
Run Code Online (Sandbox Code Playgroud)

阅读更多相关信息:http: //mongoosejs.com/docs/promises.html

  • 因为问题超过一年,所以Mongoose不支持承诺. (2认同)