深入理解JavaScript Promise链式调用与错误处理机制
作者:snakeshe1010
在JavaScript的异步编程中,Promise是一个非常重要的概念,它允许我们以链式的方式处理异步操作,使得代码更加清晰和易于管理,本文将通过一系列代码示例,深入探讨Promise的链式调用和错误处理机制,需要的朋友可以参考下
Promise链式调用基础
Promise的链式调用是通过.then()
方法实现的,该方法会返回一个新的Promise对象。这意味着我们可以在一个Promise完成后,继续进行下一个异步操作,形成一条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链中的状态传递是异步编程中的一个关键概念。一个Promise的状态(pending、fulfilled、rejected)会影响链中下一个Promise的状态。
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
也会被拒绝,并且会打印出错误信息。
详细规则说明
- 新任务的状态取决于后续处理:
- 若没有相关的后续处理,新任务的状态和前任务一致,数据为前任务的数据
const pro1 = new Promise((resolve, reject) => { console.log('学习'); console.log('中了五个亿彩票'); reject(123) }); const pro2 = pro1.then(( ) => { console.log('考试') // 后续任务只处理了成功,没处理失败,会导致pro2也会失败 // 此时pro1的状态是reject,原因是123 // pro2的状态也是rejected,原因是123 }); setTimeout(() => { console.log(pro2) // Promise {<rejected>: 123} },1000)
- 若有后续处理但还未执行,新任务挂起。
const pro1 = new Promise((resolve, reject) => { setTimeout(()=>{ resolve() }, 2000) }); const pro2 = pro1.then(( ) => { console.log('考试') }); setTimeout(() => { console.log(pro2) // Promise {<pending>},此时任务一学习需要2秒,1秒之后,任务一还没完,那么任务二也是挂起 },1000)
- 若后续处理执行了,则根据后续处理的情况确定新任务的状态
- 后续处理执行无错,新任务的状态为完成,数据为后续处理的返回值
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)
- 后续处理执行有错,新任务的状态为失败,数据为异常对象,也就是说看后续任务处理过程中是否报错,前面的任务成功,看后续任务的成功处理是否报错,前面任务失败看后续任务的处理失败过程是否报错
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)
- 后续执行后返回的是一个任务对象,新任务的状态和数据与该任务对象一致
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的后续处理,返回的是新promise,就要看新的promise状态 },1000)
实战演练
修改上一节课中发送短信的示例,我们可以更好地理解Promise链式调用的实际应用。
function sendMessage(name) { return new Promise((resolve, reject) => { // 模拟发送表白短信 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后续任务肯定也是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链式调用与错误处理的资料请关注脚本之家其它相关文章!