bluebird從3.x開始對promise的錯誤使用會有如下三種Warning,提醒你正在不正確使用bluebird,下面對這三種warning進行解釋,並說明如何避免。html
Warning: .then() only accepts functionssegmentfault
Warning: a promise was rejected with a non-errorpromise
Warning: a promise was created in a handler but none were returned from it函數
若是你看到這樣的提醒,說明你的代碼運行結果不符合你的預期。最主要緣由是傳個.then()
的參數是一個函數的執行結果,而不是函數自己。調試
function processImage(image) { // Code that processes image } getImage().then(processImage());
上面的方法就是調用processImage()
而後馬上將返回結果傳給.then()
.這裏傳給.then()
的參數就是undefined
。
爲解決這個問題,只要給.then()
傳函數就能夠了,就像這樣:code
getImage().then(processImage)
若是你有疑問爲何這裏不直接簡單粗暴地拋出TypeError,而是一個warning。由於Promises/A+標準規定對待錯誤使用時不予理睬。htm
因爲JavaScript的歷史錯誤,throw
能夠拋出任何類型的值。Promises/A+選擇繼續沿用這個錯誤,因此promise是能夠拋出一個非Error類型的值。對象
一個錯誤是一個繼承於Error的對象。它至少須要有.stack
和.message
屬性。由於錯誤一般會被根據它的不一樣來源而被分紅不一樣等級,因此一個錯誤須要包含足夠的信息,以讓高級別的handler擁有足夠的信息來生成一份有用的高級的錯誤報告。繼承
由於全部的對象都支持擁有屬性,你可能還會有疑問說,爲何必定要是一個Error對象而不能是一個普通的對象。一個錯誤對象除了要有這些屬性,還有一個一樣重要的特性就是自動採集stack trace。有了stack trace你才能容易的找到錯誤的來源。ip
你最好處理下這些warning,由於一個被拒絕的promise返回一個非Error,會致使調試很是艱難而且高成本。另外若是你拒絕一個promise只是使用最簡陋的調用reject()
,這樣你就沒辦法處理錯誤了,並且你只能告訴用戶「有地方出錯了」。
這一般說明你只是單單地忘記了聲明return
,但卻致使了該promise丟失,從而沒法關聯到promise鏈中。
例如:
getUser().then(function(user) { getUserData(user); }).then(function(userData) { // userData is undefined });
由於在第一個then裏面,getUserData(user)
沒有做爲結果return,致使第二個then認爲userData=undefined
並當即執行(由於沒有聲明return默認返回undefined
)。
解決這個問題,你只須要return這個promise:
getUser().then(function(user) { return getUserData(user); }).then(function(userData) { // userData is the user's data });
若是你知道你在作什麼,而且不想看到warning,你只須要隨便返回點什麼,好比null
:
getUser().then(function(user) { // 後臺執行,不在意運行結果 saveAnalytics(user); // 返回一個非`undefined`的值,表示咱們並無忘記return return null; });
原文連接:http://bluebirdjs.com/docs/warning-explanations.html
推薦閱讀:Bluebird promise 設置