深入理解JavaScript Promise鏈式調用與錯誤處理機制
Promise鏈式調用基礎
Promise的鏈式調用是通過.then()方法實現的,該方法會返回一個新的Promise對象。這意味著我們可以在一個Promise完成后,繼續(xù)進行下一個異步操作,形成一條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的結果,并返回2。pro3則是處理pro2的結果。
錯誤處理
.catch()方法是Promise鏈式調用中處理錯誤的常用方式。它等同于在.then()方法中只傳遞第二個參數。
new Promise((resolve, reject) => {
reject(new Error('abc'));
}).catch((err) => {
console.log('失敗了!!', err);
});
鏈式調用的深入理解

Promise鏈中的狀態(tài)傳遞是異步編程中的一個關鍵概念。一個Promise的狀態(tài)(pending、fulfilled、rejected)會影響鏈中下一個Promise的狀態(tài)。
const pro1 = new Promise((resolve, reject) => {
console.log('學習');
reject(123);
});
const pro2 = pro1.then(() => {
console.log('考試');
}, (err) => {
console.log('處理失敗', err);
});
console.log(pro2); // Promise {<rejected>: 123}
在這個例子中,pro1被拒絕,因此pro2也會被拒絕,并且會打印出錯誤信息。
詳細規(guī)則說明
- 新任務的狀態(tài)取決于后續(xù)處理:
- 若沒有相關的后續(xù)處理,新任務的狀態(tài)和前任務一致,數據為前任務的數據
const pro1 = new Promise((resolve, reject) => {
console.log('學習');
console.log('中了五個億彩票');
reject(123)
});
const pro2 = pro1.then(( ) => {
console.log('考試')
// 后續(xù)任務只處理了成功,沒處理失敗,會導致pro2也會失敗
// 此時pro1的狀態(tài)是reject,原因是123
// pro2的狀態(tài)也是rejected,原因是123
});
setTimeout(() => {
console.log(pro2) // Promise {<rejected>: 123}
},1000)
- 若有后續(xù)處理但還未執(zhí)行,新任務掛起。
const pro1 = new Promise((resolve, reject) => {
setTimeout(()=>{
resolve()
}, 2000)
});
const pro2 = pro1.then(( ) => {
console.log('考試')
});
setTimeout(() => {
console.log(pro2) // Promise {<pending>},此時任務一學習需要2秒,1秒之后,任務一還沒完,那么任務二也是掛起
},1000)
- 若后續(xù)處理執(zhí)行了,則根據后續(xù)處理的情況確定新任務的狀態(tài)
- 后續(xù)處理執(zhí)行無錯,新任務的狀態(tài)為完成,數據為后續(xù)處理的返回值
const pro1 = new Promise((resolve, reject) => {
console.log('學習')
resolve()
});
const pro2 = pro1.then(( ) => {
console.log('考試' )
return 100
});
setTimeout(() => {
console.log(pro2) // Promise {<fulfilled>: 100}
},1000)
- 后續(xù)處理執(zhí)行有錯,新任務的狀態(tài)為失敗,數據為異常對象,也就是說看后續(xù)任務處理過程中是否報錯,前面的任務成功,看后續(xù)任務的成功處理是否報錯,前面任務失敗看后續(xù)任務的處理失敗過程是否報錯
const pro1 = new Promise((resolve, reject) => {
console.log('學習')
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í)行后返回的是一個任務對象,新任務的狀態(tài)和數據與該任務對象一致
const pro1 = new Promise((resolve, reject) => {
console.log('學習')
resolve()
});
const pro2 = pro1.then(( ) => {
return new Promise((resolve, reject) => {
})
});
setTimeout(() => {
console.log(pro2) // Promise {<pending>} pro2的后續(xù)處理,返回的是新promise,就要看新的promise狀態(tài)
},1000)
實戰(zhàn)演練
修改上一節(jié)課中發(fā)送短信的示例,我們可以更好地理解Promise鏈式調用的實際應用。
function sendMessage(name) {
return new Promise((resolve, reject) => {
// 模擬發(fā)送表白短信
setTimeout(() => {
if (Math.random() <= 0.1) {
resolve(`${name} -> 帥哥程序員:我是九,你是三,除了你還是你??`);
} else {
reject(`${name} -> 帥哥程序員:你是個好人??`);
}
}, 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('帥哥程序員命犯天煞孤星,無伴終老,孤獨一生');
});
練習題
- 下面代碼的輸出結果是什么
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>,前一個任務是pending后續(xù)任務肯定也是Pending
setTimeout(() => {
console.log(pro1, pro2, pro3);
}, 2000);
// 1
// 2
// Promise {<fulfilled>: 1} Promise {<fulfilled>: 2} Promise {<fulfilled>: undefined}
- 下面代碼的輸出結果是什么
new Promise((resolve, reject) => {
resolve(1);
})
.then((res) => {
console.log(res);
return 2;
})
.catch((err) => {
return 3;
})
.then((res) => {
console.log(res);
});
// 1 2
- 下面代碼的輸出結果是什么
new Promise((resolve, reject) => {
resolve();
})
.then((res) => {
console.log(res.toString()); // 報錯
return 2;
})
.catch((err) => {
return 3;
})
.then((res) => {
console.log(res);
});
// 3
- 下面代碼的輸出結果是什么
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鏈式調用與錯誤處理機制的詳細內容,更多關于JavaScript Promise鏈式調用與錯誤處理的資料請關注腳本之家其它相關文章!
相關文章
JavaScript學習教程之cookie與webstorage
這篇文章主要給大家介紹了關于JavaScript學習教程之cookie與webstorage的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用JavaScript具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-06-06
JavaScript跨域調用基于JSON的RESTful API
這篇文章主要介紹了JavaScript跨域調用基于JSON的RESTful API的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-07-07

