深入理解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-08
Javascript實(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

