如何使用 q.nfcall if .then 部分是有条件的
How to use q.nfcall if .then part is conditional
我在服务器端 (nodejs) 使用 Q 库来避免回调金字塔。
回调金字塔如下:
var isNext = <any boolean>;
db.model1.find({a: val}).exec().
then(function(err, res){
if( res && isNext){
db.model2.find({b: val}).exec().then(function(err, res){
callback();
});
}else{
callback();
}
});
我使用 q 库来避免这样的回调金字塔:
var isNext = <any boolean>;
q.nfcall(find1(id))
.then( function( MODEL1 ){
var deferred = q.defer();
if( MODEL1 && isNext){
deferred.promise = find2( id );
}else{
deferred.resolve(MODEL1);
}
return deferred.promise;
})
.fail(function(err){
console.log('--> err : ' + JSON.stringify(err));
})
.done(function(){
console.log('update done..');
// main callback
});
find1 和 find2 函数如下:
function find1(id){
var deferred = q.defer();
db.model1.findOne({_id: id}).exec()
.then(function(model){
if( model ){
// some operation
deferred.resolve( model );
}else{
deferred.reject( 'error' );
}
},function(err){
deferred.reject( err );
}
);
return deferred.promise;
}
function find2(id){
var deferred = q.defer();
db.model2.findOne({_id: id}).exec()
.then(function(model){
if( model ){
// some operation
deferred.resolve( model );
}else{
deferred.reject( 'error' );
}
},function(err){
deferred.reject( err );
}
);
return deferred.promise;
}
所以,问题是,当使用 Q 库时,.then 部分没有被执行。
在这个问题中,调用总是进入执行的 .fail 部分。
我期望的是执行应该在执行 find1() 调用时进入 .then 部分。
您的 find1
函数已经是 return 承诺 - 您 不应该 不能将它与 Q.nfcall
一起使用。
随心所欲
var isNext = <any boolean>;
find1(id)
.then(function(MODEL1) {
if (MODEL1 && isNext) {
return find2(id);
} else {
return MODEL1; // you can just return plain values as well, btw
}
})
.fail(function(err) {
console.log('--> err : ' + JSON.stringify(err));
})
.done(function() {
console.log('update done..');
// main callback
});
注意你应该avoid the deferred antipattern。那些 exec
调用已经 return 承诺,所以你可能想要做的就是将它们转换为 Q
承诺并拒绝虚假结果。
function find1(id) {
return q(db.model1.findOne({_id: id}).exec())
.then(function(model) {
if (model) {
// some operation
return model;
} else {
throw new Error('error');
}
});
}
function find2(id) {
// analogous
}
我在服务器端 (nodejs) 使用 Q 库来避免回调金字塔。
回调金字塔如下:
var isNext = <any boolean>;
db.model1.find({a: val}).exec().
then(function(err, res){
if( res && isNext){
db.model2.find({b: val}).exec().then(function(err, res){
callback();
});
}else{
callback();
}
});
我使用 q 库来避免这样的回调金字塔:
var isNext = <any boolean>;
q.nfcall(find1(id))
.then( function( MODEL1 ){
var deferred = q.defer();
if( MODEL1 && isNext){
deferred.promise = find2( id );
}else{
deferred.resolve(MODEL1);
}
return deferred.promise;
})
.fail(function(err){
console.log('--> err : ' + JSON.stringify(err));
})
.done(function(){
console.log('update done..');
// main callback
});
find1 和 find2 函数如下:
function find1(id){
var deferred = q.defer();
db.model1.findOne({_id: id}).exec()
.then(function(model){
if( model ){
// some operation
deferred.resolve( model );
}else{
deferred.reject( 'error' );
}
},function(err){
deferred.reject( err );
}
);
return deferred.promise;
}
function find2(id){
var deferred = q.defer();
db.model2.findOne({_id: id}).exec()
.then(function(model){
if( model ){
// some operation
deferred.resolve( model );
}else{
deferred.reject( 'error' );
}
},function(err){
deferred.reject( err );
}
);
return deferred.promise;
}
所以,问题是,当使用 Q 库时,.then 部分没有被执行。 在这个问题中,调用总是进入执行的 .fail 部分。 我期望的是执行应该在执行 find1() 调用时进入 .then 部分。
您的 find1
函数已经是 return 承诺 - 您 不应该 不能将它与 Q.nfcall
一起使用。
随心所欲
var isNext = <any boolean>;
find1(id)
.then(function(MODEL1) {
if (MODEL1 && isNext) {
return find2(id);
} else {
return MODEL1; // you can just return plain values as well, btw
}
})
.fail(function(err) {
console.log('--> err : ' + JSON.stringify(err));
})
.done(function() {
console.log('update done..');
// main callback
});
注意你应该avoid the deferred antipattern。那些 exec
调用已经 return 承诺,所以你可能想要做的就是将它们转换为 Q
承诺并拒绝虚假结果。
function find1(id) {
return q(db.model1.findOne({_id: id}).exec())
.then(function(model) {
if (model) {
// some operation
return model;
} else {
throw new Error('error');
}
});
}
function find2(id) {
// analogous
}