2013-11-14 33 views
0

我試圖創建一個使用q.js的延遲包裝,這樣我就可以在自定義錯誤類中包裝錯誤(字符串),然後它們被then()fail()中的承諾傳回。這是我目前在做什麼:Promise - 在deferred.reject期間包裝錯誤

var getDeferred = function() { 

    var deferred = q.defer(); 

    var reject = deferred.reject; 
    deferred.reject = function(error) { 

     if (!(error instanceof MyErrorClass)) 
      error = new MyErrorClass(error) 

     return reject.apply(deferred, arguments); 
    } 

    return deferred; 
} 

這樣的想法是,用戶會做類似

var deferred = getDeferred(); 

deferred.promise.fail(function(err) { 
    // err should now be instance of MyErrorClass and NOT a string 
}) 

deferred.reject('A string error') 

,並期望得到MyErrorClassfail()處理程序,而不是字符串傳遞到deferred.reject

上面的代碼工作,但它不是理想的 - 我知道我不應該猴子補丁deferred.reject。但有沒有更好的方法來做到這一點?

+0

那麼你不應該一般使用延遲。編寫手動代碼來promisify回調API是一個巨大的代碼浪費。不幸的是,Q.nbind不會自動包裝字符串錯誤,但您始終可以編寫自己的實現。 – Esailija

+0

@Esailija - 我只是想感謝你的評論,這很清楚我對承諾的理解。本來我認爲創建延期是規範的方式來創造一個新的承諾。我一直在玩q.js,現在事情變得更直接。 – bluepnume

回答

1

它的漂亮/多諾面向這樣的:

var getDeferred = function() { 

    var deferred = q.defer(); 

    deferred.promise = deferred.promise.then(null, function(error) { 
     if (!(error instanceof MyErrorClass)) 
      error = new MyErrorClass(error) 

     throw error 
    } 

    return deferred; 
} 

這樣,你只是附加的錯誤處理程序,這將發生變異的任何非MyErrorClass錯誤。這似乎是一個奇怪的情況下,使用一般,但...

+0

美麗,謝謝。我知道這是一個奇怪的用例,它是說服人們轉向對現有代碼庫的承諾,同時支持當前回調 - 湯所做的一些相同的事情之一。 – bluepnume

0

只需在失敗的情況下使用then地圖:

actualPromise.then(null, function(error) { 
    if (!(error instanceof MyErrorClass)) 
     error = new MyErrorClass(error) 
    throw error; 
}) 
.fail(function(err) { 
    // err is now an instance of MyErrorClass and NOT a string 
}); 

如果您需要的包裝功能,使用一個函數,它的actualPromise並調用then與上面的代碼就可以了。