2014-10-29 194 views
-3

我有以下方法時處理異常。最佳實踐使用Q.promise

我遇到的問題是,如果someObject爲空或沒有所有適當的嵌套屬性,則拋出異常並且承諾永遠不會解析。我實際上看到異常的唯一方法是如果我在調用函數上有.fail,但仍然不能解決承諾。

如何,我現在可以看到除了將實施例:

myLib.getId.then(function() { 
    // something 
}).fail(function(err) { 
    console.log(err); 
}); 

我知道2點的方式來解決這個問題,但我不知道,如果是兩種處理這樣的事情最好的辦法。

選項1(使用盡我Q.promise內/捕獲):

module.exports.getId = function(someObject) { 

    var myId = null; 

    return Q.Promise(function(resolve, reject, notify) { 

     try { 
     // Loop through all the id's 
     someObject.user.player._id.forEach(function (id) { 

      if (id.root == "1.2.3.4.5.6") { 
       myId = id.extension; 
      } 
     }); 

     } catch(e) { 
     reject(e); 
     } 

     resolve(myId); 
    }); 
}; 

選項2(明確檢查someObject.user.player._id存在):

module.exports.getId = function(someObject) { 

    var myId = null; 

    return Q.Promise(function(resolve, reject, notify) { 

     ifi(someObject.user.player._id exists..) { 

     // Loop through all the id's 
     someObject.user.player._id.forEach(function (id) { 

      if (id.root == "1.2.3.4.5.6") { 
       myId = id.extension; 
      } 
     }); 

     resolve(myId); 
     } else { 
     reject('invalid object'); 
     } 
    }); 
}; 

選項1似乎聞到時髦,因爲我使用try/catch內的承諾。選項2解決了我的問題,但任何其他意外的異常都不會被捕獲。

有沒有更好的方法我應該處理這個問題?

+0

不是downvoter,但我想知道 - 爲什麼你在同步代碼中使用承諾開始?另外 - 如果你使用承諾,拋出和拒絕是同樣的事情。 – 2014-10-29 16:41:33

+0

我在同步代碼b/c中使用promise,它是庫的一部分,我不希望用戶必須知道lib中的哪些方法是同步的,哪些不是,所以我讓它們都是異步的。我知道扔和拒絕是一樣的。我實際上並沒有拋出任何東西。 – Catfish 2014-10-29 16:54:13

+1

當然你是 - 當你做'a.b.c ...'時,不知道你在那裏寫了什麼代碼,可能會拋出一些代碼,以便在捕獲完成之後就可以拋出'rejext'。 – 2014-10-29 16:58:03

回答

-1

你的第一個例子中有幾個問題:

  • 當你捕獲異常,您拒絕的承諾,那麼解決的承諾。這違反了諾言合同;您可以通過致電try內的解決方案解決問題,而不是在外面。
  • 通過使用try/catch,你可能會吞下意想不到的錯誤。那是你假設唯一的錯誤將來自someObject.user.player._id不存在。目前這可能是真實的,但不能保證隨着代碼的發展而保持真實。

通過嚴格測試已知錯誤情況,您知道您不會吞嚥意外錯誤。因此,我會用你的第二個例子。

+0

@downvoter請解釋downvotes,所以我可以刪除/改善答案 – 2014-10-29 16:44:12

+1

不是我,但我不明白這是如何解決這個問題除了「這是我認爲,這樣和那樣的」 – 2014-10-29 16:45:27

+0

Downvoting巨魔今天在這裏 – Catfish 2014-10-29 16:54:49