2017-10-11 57 views
2

Promise被拒絕,而.then()出現在.catch()之後時,拒絕被捕獲,但接下來仍然運行(請參閱下面的示例then)。Promise被拒絕時,Promise連鎖訂單有什麼作用?

然而,當一個Promise解決,並.then().catch()之前,拒絕被捕獲,並.then()不會被調用。

爲什麼這兩種情況的行爲有所不同,以及在發生拒絕後發生.then()調用會有什麼用處?

var then = Promise.reject() 
    .catch(() => 'catch') 
    .then(() => document.getElementById('then').innerHTML = 'then'); 

var noThen = Promise.reject() 
    .then(() => document.getElementById('noThen').innerHTML = 'then') 
    .catch((err) => 'catch'); 

https://jsfiddle.net/mmyj61dd/

編輯:

一個有趣的相關例子,說明.then()如何依賴於它傳遞函數的參數:

var then = Promise.reject() 
    .then((undefined, err) => 'catch') 
    .then((asdf) => document.getElementById('then').innerHTML = 'then'); 

var noThen = Promise.reject() 
    .then((asdf) => document.getElementById('noThen').innerHTML = 'then') 
    .then((undefined, err) => 'catch'); 

只有(undefined, err) => 'catch'功能得到在這兩種情況下稱爲這裏。

https://jsfiddle.net/ro0cv1p1/2/

+0

但它具有邏輯意義,不是嗎? – Li357

+0

'catch'就像是在'finally'之後'then'因此最終的行爲類似於Javascript - > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try ...趕上 – Keith

+0

取決於你如何編寫你的.then。回調的第一個參數在履行承諾時運行,第二個(可選)參數在承諾被拒絕時運行。趕上,然後不是對立的。如果你願意,你可以使用第二個參數來「然後」,而不是單獨的「catch」。寫不同的方法來寫同一件事。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then和https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ Global_Objects/Promise/catch解釋它 – ADyson

回答

2

它類似於傳統的try..catch

try { 
    foo(); 
    bar(); 
} catch (e) { 
    baz(); 
} 

這是從不同:

try { 
    foo(); 
} catch (e) { 
    baz(); 
} 

bar(); 

實際應用是簡單的解釋:嘗試一些(啓動一個承諾),如果失敗產生一些默認值,則繼續異步鏈。例如:

fetch('http://example.com') 
    .then(result => result.somevalue) 
    .catch(e => 'default value') 
    .then(value => alert(value)); 

這或者顯示somevalue取出從example.comdefault value

1

沒有then(在then實際上沒有第一個回調,因爲第二個回調的確是趕上替代)將被調用,直到鏈中的你「抓拒絕」按鈕,返回「積極」的價值 - catch函數應該返回任何非未解決的承諾,不應該拋出和錯誤來「修復」鏈中的承諾。 如果catch將返回此類值,則將調用then,它也將返回值爲catch作爲參數。 而且,如果調用then並拋出錯誤或返回被拒絕的承諾,則鏈中的下一個then將不會被調用,直到「捕獲拒絕」爲止。

E.g.

let resolvedPromiseAfterAll = Promise.reject() 
    .then(() => 'then') // <-not called 
    .catch(e => { console.log(e); throw e; }) // <- only error log 
    .then(() => 'then 2') // <- still not called because previous catch didn't resolve the promise 
    .catch(e => 'catched') // <- return 'catched' that is equiv to Promise.resolve('catched') 
    .then(val => { console.log('then 2', val); return 'ok'; }) // <-- this promise should finally be called because previous catch didn't throw Error or returned rejected Promise. We also get 'catch' as first param in then callback so the console.log is 'then 2 catched'. 

這是怎麼無極鏈的作品 - 你可以從拒絕承諾獲得通過捕捉拒絕原因和返回的東西,這不是錯誤解決,你可以「休息」解決承諾通過返回拒絕承諾或拋出Error附then

這是相當強大的功能,在你實現你決定做什麼的排斥反應,所以如果你會做這樣的事情(不catch ES): somePromise.then().then().then() 意味着你不想調用任何下列then的回調如果在任何階段出現問題。 但是,如果您想要處理某些then上的Promise拒絕,請在then之後添加catch

它與try/catch類似 - 如果在此塊的前一行中引發異常,try塊中的部分代碼將不會被調用。

順便說一句,你的固定提琴例如:https://jsfiddle.net/ro0cv1p1/3/

+0

感謝您的小提琴更新。直到現在我纔看到 – maxhud

相關問題