深入理解JavaScript Promise鏈?zhǔn)秸{(diào)用與錯(cuò)誤處理機(jī)制
Promise鏈?zhǔn)秸{(diào)用基礎(chǔ)
Promise的鏈?zhǔn)秸{(diào)用是通過.then()
方法實(shí)現(xiàn)的,該方法會(huì)返回一個(gè)新的Promise對(duì)象。這意味著我們可以在一個(gè)Promise完成后,繼續(xù)進(jìn)行下一個(gè)異步操作,形成一條Promise鏈。
const pro1 = new Promise((resolve, reject) => { setTimeout(() => { resolve(1); }, 1000); }); const pro2 = pro1.then((data) => { console.log(data); return data + 1; }); const pro3 = pro2.then((data) => { console.log(data); });
在上面的例子中,pro1
在1秒后解析為1,pro2
接著處理pro1
的結(jié)果,并返回2。pro3
則是處理pro2
的結(jié)果。
錯(cuò)誤處理
.catch()
方法是Promise鏈?zhǔn)秸{(diào)用中處理錯(cuò)誤的常用方式。它等同于在.then()
方法中只傳遞第二個(gè)參數(shù)。
new Promise((resolve, reject) => { reject(new Error('abc')); }).catch((err) => { console.log('失敗了??!', err); });
鏈?zhǔn)秸{(diào)用的深入理解
Promise鏈中的狀態(tài)傳遞是異步編程中的一個(gè)關(guān)鍵概念。一個(gè)Promise的狀態(tài)(pending、fulfilled、rejected)會(huì)影響鏈中下一個(gè)Promise的狀態(tài)。
const pro1 = new Promise((resolve, reject) => { console.log('學(xué)習(xí)'); reject(123); }); const pro2 = pro1.then(() => { console.log('考試'); }, (err) => { console.log('處理失敗', err); }); console.log(pro2); // Promise {<rejected>: 123}
在這個(gè)例子中,pro1
被拒絕,因此pro2
也會(huì)被拒絕,并且會(huì)打印出錯(cuò)誤信息。
詳細(xì)規(guī)則說明
- 新任務(wù)的狀態(tài)取決于后續(xù)處理:
- 若沒有相關(guān)的后續(xù)處理,新任務(wù)的狀態(tài)和前任務(wù)一致,數(shù)據(jù)為前任務(wù)的數(shù)據(jù)
const pro1 = new Promise((resolve, reject) => { console.log('學(xué)習(xí)'); console.log('中了五個(gè)億彩票'); reject(123) }); const pro2 = pro1.then(( ) => { console.log('考試') // 后續(xù)任務(wù)只處理了成功,沒處理失敗,會(huì)導(dǎo)致pro2也會(huì)失敗 // 此時(shí)pro1的狀態(tài)是reject,原因是123 // pro2的狀態(tài)也是rejected,原因是123 }); setTimeout(() => { console.log(pro2) // Promise {<rejected>: 123} },1000)
- 若有后續(xù)處理但還未執(zhí)行,新任務(wù)掛起。
const pro1 = new Promise((resolve, reject) => { setTimeout(()=>{ resolve() }, 2000) }); const pro2 = pro1.then(( ) => { console.log('考試') }); setTimeout(() => { console.log(pro2) // Promise {<pending>},此時(shí)任務(wù)一學(xué)習(xí)需要2秒,1秒之后,任務(wù)一還沒完,那么任務(wù)二也是掛起 },1000)
- 若后續(xù)處理執(zhí)行了,則根據(jù)后續(xù)處理的情況確定新任務(wù)的狀態(tài)
- 后續(xù)處理執(zhí)行無錯(cuò),新任務(wù)的狀態(tài)為完成,數(shù)據(jù)為后續(xù)處理的返回值
const pro1 = new Promise((resolve, reject) => { console.log('學(xué)習(xí)') resolve() }); const pro2 = pro1.then(( ) => { console.log('考試' ) return 100 }); setTimeout(() => { console.log(pro2) // Promise {<fulfilled>: 100} },1000)
- 后續(xù)處理執(zhí)行有錯(cuò),新任務(wù)的狀態(tài)為失敗,數(shù)據(jù)為異常對(duì)象,也就是說看后續(xù)任務(wù)處理過程中是否報(bào)錯(cuò),前面的任務(wù)成功,看后續(xù)任務(wù)的成功處理是否報(bào)錯(cuò),前面任務(wù)失敗看后續(xù)任務(wù)的處理失敗過程是否報(bào)錯(cuò)
const pro1 = new Promise((resolve, reject) => { console.log('學(xué)習(xí)') resolve() }); const pro2 = pro1.then(( ) => { console.log('考試' ) throw new Error('睡著了!!') return 100 }); setTimeout(() => { console.log(pro2) // Promise {<rejected>: Error: 睡著了!!at <anonymous>:8:9} },1000)
- 后續(xù)執(zhí)行后返回的是一個(gè)任務(wù)對(duì)象,新任務(wù)的狀態(tài)和數(shù)據(jù)與該任務(wù)對(duì)象一致
const pro1 = new Promise((resolve, reject) => { console.log('學(xué)習(xí)') resolve() }); const pro2 = pro1.then(( ) => { return new Promise((resolve, reject) => { }) }); setTimeout(() => { console.log(pro2) // Promise {<pending>} pro2的后續(xù)處理,返回的是新promise,就要看新的promise狀態(tài) },1000)
實(shí)戰(zhàn)演練
修改上一節(jié)課中發(fā)送短信的示例,我們可以更好地理解Promise鏈?zhǔn)秸{(diào)用的實(shí)際應(yīng)用。
function sendMessage(name) { return new Promise((resolve, reject) => { // 模擬發(fā)送表白短信 setTimeout(() => { if (Math.random() <= 0.1) { resolve(`${name} -> 帥哥程序員:我是九,你是三,除了你還是你??`); } else { reject(`${name} -> 帥哥程序員:你是個(gè)好人??`); } }, 1000); }); } sendMessage('kitty') .catch((reply) => sendMessage('cathy')) .catch((reply) => sendMessage('Linda')) .then((reply) => { console.log(reply); console.log('帥哥程序員終于找到了自己的伴侶'); }) .catch((reply) => { console.log(reply); console.log('帥哥程序員命犯天煞孤星,無伴終老,孤獨(dú)一生'); });
練習(xí)題
- 下面代碼的輸出結(jié)果是什么
const pro1 = new Promise((resolve, reject) => { setTimeout(() => { resolve(1); }, 1000); }); const pro2 = pro1.then((data) => { console.log(data); return data + 1; }); const pro3 = pro2.then((data) => { console.log(data); }); // console.log(pro1, pro2, pro3); // promise<pending>, promise<pending>, promise<pending>,前一個(gè)任務(wù)是pending后續(xù)任務(wù)肯定也是Pending setTimeout(() => { console.log(pro1, pro2, pro3); }, 2000); // 1 // 2 // Promise {<fulfilled>: 1} Promise {<fulfilled>: 2} Promise {<fulfilled>: undefined}
- 下面代碼的輸出結(jié)果是什么
new Promise((resolve, reject) => { resolve(1); }) .then((res) => { console.log(res); return 2; }) .catch((err) => { return 3; }) .then((res) => { console.log(res); }); // 1 2
- 下面代碼的輸出結(jié)果是什么
new Promise((resolve, reject) => { resolve(); }) .then((res) => { console.log(res.toString()); // 報(bào)錯(cuò) return 2; }) .catch((err) => { return 3; }) .then((res) => { console.log(res); }); // 3
- 下面代碼的輸出結(jié)果是什么
new Promise((resolve, reject) => { throw new Error(1); }) .then((res) => { console.log(res); return new Error('2'); }) .catch((err) => { throw err; return 3; }) .then((res) => { console.log(res); }); // pro1 reject Error(1) // pro2 reject Error(1) // pro3 reject Error(1) // pro4 reject Error(1) // 什么都不打印
- 下面的代碼輸出什么
const promise1 = new Promise((resolve, reject) => { setTimeout(() => { reject(); }, 1000); }); const promise2 = promise1.catch(() => { return 2; }); console.log('promise1', promise1); console.log('promise2', promise2); // Promise1 {<pending>} // promise2 Promise {<pending>} setTimeout(() => { console.log('promise1', promise1); console.log('promise2', promise2); }, 2000); // promise1 Promise {<rejected>: undefined} // promise2 Promise {<fulfilled>: 2}
以上就是深入理解JavaScript Promise鏈?zhǔn)秸{(diào)用與錯(cuò)誤處理機(jī)制的詳細(xì)內(nèi)容,更多關(guān)于JavaScript Promise鏈?zhǔn)秸{(diào)用與錯(cuò)誤處理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解ES6之a(chǎn)sync+await 同步/異步方案
這篇文章主要介紹了詳解ES6之a(chǎn)sync+await 同步/異步方案,本文以最簡(jiǎn)明的方式來疏通 async + await,有興趣的可以了解下2017-09-09微信小程序開發(fā)實(shí)現(xiàn)首頁彈框活動(dòng)引導(dǎo)功能
自己x實(shí)現(xiàn)的一個(gè)比較簡(jiǎn)單微信彈窗功能,主要就是教會(huì)大家對(duì)微信彈窗的用法和理解,這篇文章主要給大家介紹了關(guān)于微信小程序如何實(shí)現(xiàn)首頁彈框活動(dòng)引導(dǎo)功能的相關(guān)資料,需要的朋友可以參考下2021-08-08Javascript實(shí)現(xiàn)視頻輪播在pc端與移動(dòng)端均可
用Javascript實(shí)現(xiàn)視頻輪播,畢竟是客戶的需求嗎?所以盡量實(shí)現(xiàn)下,下面有個(gè)實(shí)現(xiàn)視頻輪播的示例,pc端與移動(dòng)端均可以實(shí)現(xiàn),感興趣的朋友可以了解下2013-09-09