2015-02-12 67 views
1

所以我有几个函数都会对服务进行异步调用。我不想让他们在前一个完成后执行,但只有在前一个没有失败时才能执行。它看起来像这样:Promise chaining(angular javascript)

var fn1 = function() { 
    var promise = aService.fn1(); 
    var successCallback = function(response) { 
     return true; 
    }; 
    var errorCallback = function() { 
     return false; 
    }; 
    return promise.then(successCallback, errorCallback); 
}; 
var fn2 = function() { 
    var promise = aService.fn2(); 
    var successCallback = function(response) { 
     return true; 
    }; 
    var errorCallback = function() { 
     return false; 
    }; 
    return promise.then(successCallback, errorCallback); 
}; 
var fn3 = function() { 
    var promise = aService.fn3(); 
    var successCallback = function(response) { 
     return true; 
    }; 
    var errorCallback = function() { 
     return false; 
    }; 
    return promise.then(successCallback, errorCallback); 
}; 

fn1().then(function(resp){ 
    if (resp) 
    { 
     fn2().then(function(resp){ 
      if (resp) 
      { 
       fn3().then(function(resp){ 
        if (resp) 
        { 
         // all functions have been called in order were successful 
        } 
       }); 
      } 
     }); 
    } 
}); 

最后的执行看起来很糟糕,更多的功能被添加到这个链。我不想知道是否有另一种方式可以构造这种方式,所以它的行为相同,但不会创建大型链接异步调用树。如果我能把它保持在一个很好的缩进位置上。谢谢!

回答

3

你必须修改错误回调返回$q.reject()而不是false,即:

var fn1 = function() { 
    var promise = aService.fn1(); 
    var successCallback = function(response) { 
     // no return needed, unless the next stage 
     // requires the results of this stage 
    }; 
    var errorCallback = function() { 
     return $q.reject(); 
    }; 
    return promise.then(successCallback, errorCallback); 
}; 

的链接变成:

fn1() 
    .then(function() { 
     return fn2(); 
    }) 
    .then(function() { 
     return fn3(); 
    }) 
    .then(function() { 
     // ALL SUCCEEDED HERE 
    }); 

事实上,你甚至不用写在f1痛苦的代码,f2f3,即下面也将做的工作:

aService.fn1() 
    .then(function() { 
     return aService.fn2(); 
    }) 
    .then(function() { 
     return aService.fn3(); 
    }) 
    .then(function() { 
     // ALL SUCCEEDED HERE 
    }); 
+0

谢谢!这工作完美。我不能使用你的第三个解决方案,虽然在我的真实代码中,我在fn1,fn2和fn3的错误和成功回调中有一些逻辑。然而,你提供的第二个解决方案正是我所期待的。 – 2015-02-12 09:30:07

+0

@ martingo89请参阅https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-thensuccess-fail-anti-pattern – 2015-02-12 10:03:15

1

如果您的服务功能已经promisified,你可以让事情变得极短:

aService.fn1() 
.then(aService.fn2.bind(aService)) 
.then(aService.fn3.bind(aService)) 
.then(function(){ 
    // all functions have been called in order and were successful 
});