2015-02-12 70 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 
});