一樣實現一個功能,不一樣人的實現差千里。老規矩,脫離業務場景的討論都是無用的,因此咱們先約定下業務場景:後端
PM同窗,跑來給你捶背,按摩的求你給商城首頁新增一個活動信息展現的需求。bash
A同窗,剛畢業,很是積極,這個不就是調用一下接口,把活動信息展現出來不就能夠了,主動找PM小姐姐把活給接過來了。而後寫了以下代碼: 首先定義了一個獲取活動信息的方法:post
const getActivityInfo = ()=>{
return request.post(url,body);
}
複製代碼
而後在業務層調用優化
//...原始首頁業務邏輯...
const info = await getActivityInfo();
showActivety(info);
//...原始首頁業務邏輯...
複製代碼
就這樣很快的完成了功能,提測上線了,獲得了PM小姐姐的表揚。 可是好景不長,一天作活動,流量激增,後端獲取服務的接口掛了,getActivityInfo 方法拋出了異常,直接中斷了原始的業務邏輯,整個頁面掛了。ui
PM小姐姐很生氣的過來,問:只是活動系統掛了而已,怎麼如今整個頁面都掛了。被譴責一番,可是還好沒泄氣,請教了身邊工做一年的同事B,而後告訴他,你這要處理異常,避免中斷主流程,影響了核心的業務。咣咣咣,很快優化了邏輯:url
//...原始業務邏輯...
try {
const info = await getActivityInfo();
showActivety(info);
} catch (error) {
console.error('活動系統服務異常!');
}
//...原始業務邏輯...
複製代碼
很快,又上線了,A開心的繼續工做。spa
過了一段時間,PM小姐姐又氣哄哄的跑了過來,怎麼回事,剛推廣作活動,如今網頁加載好慢。很快查出了問題,因爲訪問量過大,getActivityInfo 服務響應過慢,直接影響了核心業務的響應速度。因而A同窗又請教了一個經驗比較足的同事,告訴了他解決方法:code
try {
const info = await Promise.race([
getActivityInfo(),
new Promise((resolve, reject) => {
// 後端服務,響應過慢,超時100ms熔斷
const timeOutMs = 100;
setTimeout(() => {
resolve({});
}, timeOutMs);
})
]);;
showActivety(info);
} catch (error) {
console.error('活動系統服務異常!');
}
複製代碼
此次好了,加了熔斷機制,非核心業務若是響應過慢,直接放棄,保障核心業務需求。很開心的又提測了,可是此次經理不放心了,過來 Review 代碼,一看不滿意,這代碼之後怎麼維護,每一個地方調用活動信息的時候,都得增超時機制,多麻煩,因而指點一二:接口
const getActivityInfo = () => {
try {
const info = await Promise.race([
request.post(url, body),
new Promise((resolve, reject) => {
// 後端服務,響應過慢,超時100ms熔斷
const timeOutMs = 100;
setTimeout(() => {
resolve({});
}, timeOutMs);
})
]);
return info;
} catch (error) {
console.error('活動系統服務異常!');
return {};
}
}
//...原始業務邏輯...
const info = await getActivityInfo();
showActivety(info);
//...原始業務邏輯...
複製代碼
此次業務代碼一下工整了,少了try catch,同時,之後在別處調用活動信息的時候,就不須要再考慮各類異常狀況處理了。get
同窗A:我好難...