问题
[I will answer this question but feel free to add solutions or other problems that may occur]
Working on a nodejs project where we use q promises heavily and mongoose I have found some unintuitive hickups combining the two.
First one is that mongoose promise does not have .fail
or .catch
.
Another one is that Model.create returns a promise that calls the resolve function with mutliple arguments when resolved. If this goes through Q then Q will call the resolve with only the first argument.
Please feel free to add more problems that may occur; I will put how I solved these things in an answer.
回答1:
You can simply use the Q function to cast Mongoose promises to "proper" Q ones - this works in fact with every thenable.
So just use
Q(someMongoosePromise) .then(…).catch(…);
Multiple arguments are a different problem. However, there is a very simple hack: convert them to an array and work with that.
Q(Model.create([doc1,doc2]).then(Array)) .spread(function(d1, d2){ … });
(This solution doesn't apply in case Model.create
returns a promise for a single number)
回答2:
Because mongoose promises do not have a .catch
or .fail
(Note that q will remove these from their library as well) you can not return a failing mongoose promise on a q stack that ends with either .catch or .fail without turning it into a q promise first. Here is how I did that (this has been answered elsewhere on stack as well):
function something(){
return q()//make sure this function returns a promise instead of an unhandled error
.then(function(){
//do some stuff
})
.then(function(){
return someMongoosePromise
.then(function resolve(res){//make sure to return a q promise if this function is called in a stack that has
//.then.then.then(function(){return something();}).fail(...
return q.resolve(res);
},function reject(err){
return q.reject(err);
}
);
});
}
Second problem I encountered was that Model.create([doc1,doc2]) resolves the promise with multiple arguments but when going through q q only calls resolve with one argument:
q()
.then(function(){
return Model.create([doc1,doc2]);
})
.then(function(docs){
docs===doc1;//David Copperfield took doc2
});
the solution is about the same as the first one:
q()
.then(function(){
return Model.create([doc1,doc2])
.then(function(){//let mongoose resolve the promise
var ret=[],i=arguments.length;
while(--i>-1){
ret.push(arguments[i];
}
return q.resolve(ret);
});
})
.then(function(docs){
docs===[doc1,doc2];
});
来源:https://stackoverflow.com/questions/28978485/mongoose-promise-and-q-promise