2014-12-19 16 views
0

我一直在嘗試向我們的代碼庫添加更好的承諾架構,以便減少函數之間的硬編碼關係,並且承諾對此非常有用。但是,偶爾我會遇到一些困難,找出設計方法的最佳方法。JavaScript承諾架構:靜默一個錯誤

在這種情況下,這是我的廢止功能(排序的僞碼)

/* public function */ 
function validateUserPreference() { 
return askUserPreference().then(saveUserPreference); 
} 

/* uses several ajax calls and modal dialogs to confirm the user's preference, 
    returning true/false in a promise object. */ 
function askUserPreference() ... 

/* Saves the user's preference to the server. Usually, try to call this 
    before resolving validateUserPreference, as a convenience to those running it. */ 
function saveUserPreference() ... 

現在,這裏是棘手位;錯誤解決。通常,當一系列的承諾失敗時,你只是想向用戶拋出一個對話,告訴他們發生了什麼壞事。但在這種情況下,我想嘗試保存用戶的偏好,但如果它不管理,它不是一個阻擋程序。我不想只添加then(saveUserPreference)並返回最初的承諾,因爲一旦validateUserPreference()返回,頁面將立即提交。

基本上,我想從askUserPreferencethen功能沿着價值傳遞,而不是直到對方承諾完成解決它,但後來不知怎的忽略任何reject故障所出現的saveUserPreference,並返回相同的值。

我目前正在使用Dojo的承諾API,所以我可以利用他們擁有的任何庫。

回答

1

我想像你不得不做這樣的事情:

/* public function */ 
function validateUserPreference() { 
    var resolution = askUserPreference(); 
    return resolution 
    .then(saveUserPreference) 
    .then(null, function(){ 
     return resolution; 
    }); 
}); 

這裏有一個概念證明表明.then()創建一個新的承諾,可以不考慮解決先前承諾的拒絕:

new Promise(function (resolve, reject){ 
    reject(false); 
}).then(null, function(){ 
    return true; 
}).then(function(value){ 
    console.log('RESOLVED :)', value); 
}, function(value){ 
    console.warn('REJECTED :(', value); 
}); 

在瀏覽器的控制檯中運行該命令將導致RESOLVED :) true將輸出發送到控制檯。

+0

這可能是我錯誤的記憶,但我想我記得如果一個承諾被拒絕,那麼拒絕會通過「下鏈」;所以你的方法中的最後一個'.then'仍然會返回爲saveUserPreference的拒絕(儘管不是ajax錯誤,它至少會返回askUserPreference的結果)。 – Katana314

+0

@ Katana314不,那是不正確的。看我的編輯。 – idbehold

+0

@ Katana314如果你**想繼續拒絕'then'鏈,你可以用'throw'替換第二個代碼塊第4行的'return'。 – idbehold