我正在使用蓝鸟的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()方法返回单个对象。
非常感谢任何帮助!
答案 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({})
// ..