JavaScript:Promise的链式调用
在理解Promise的链式调用之前,我们需要先理清 then 方法的原理。
关于 then 的三个知识点
-
then 方法返回的也是一个 Promise 对象,并且这个 Promise 对象的状态由 then 内部的回调函数的执行结果来决定,不取决于 then 中执行的是成功的回调还是失败的回调。即:then执行的回调函数的 return 值。
-
then 返回的Promise 对象的状态和回调函数的 return 值之间的关系
- 如果回调函数的 return 值是 非promise类型的值 , 则 then 方法返回的promise对象的状态为成功fulfilled ,状态值为 return 的值。
// 不论是执行.then中成功的回调函数失败的回调,return的结果都是非promise类型的值 // 所以 .then 返回的promise对象的状态都为成功fulfilled // 如果执行的是成功的回调,则状态值为 11111, 如果执行的是失败的回调,则状态值为22222 // 状态值为下一个.then的成功或失败的回调函数的实参 .then(()=>{ return 11111; },()=>{ console.log(22222); })
-
如果回调函数没有 return 值,根据 js 中的函数的定义,函数的默认 return 值为 undefined,而 undefined 也是 非promise类型的值,所以结果同上。
-
如果回调函数的 return 值 是 promise对象 ,则 then 方法返回的promise对象的状态则取决于这个 return 中的 promise对象的内部状态, 内部为resolve, 则 then 返回的状态为fulfilled,内部为reject,则 then 返回的状态为rejected,状态值为resolve / reject 调用时传入的实参。
/* 当 .then 执行成功的回调时,返回的是一个 promise 对象,那么 return 的结果取决于 这个 promise 对象的内部状态,即: 如果执行 resolve() ,则 then 返回的状态为fulfilled 如果执行 reject() ,则 then 返回的状态为rejected 状态值为执行resolve() / reject() 所传递的实参,如果没有,则为 undefined */ .then((value)=>{ return new Promise((resolve,reject)=>{ if(10>1){ resolve(); }else{ reject(); } }) },()=>{ console.log(22222); })
-
如果回调函数 抛出错误,则 then 方法返回的promise对象的状态为rejected,状态值就是你抛出的值。
.then( ()=>{ throw "error"; } )
-
catch 和 then 之间的关系
如果每一个then只有一个回调函数,那么catch会捕捉任意一个promise的reject状态
.catch((err) => console.log('rejected', err));
//等同于
.then(null, (err) => console.log("rejected:", er));
理解了以上三个知识点之后,就可以大致理解Promise链式调用了。
Promise的链式调用
1| new Promise((resolve,reject)=>{
2| // 随机生成0到100之间的数
3| let a = Math.random() * 100;
4| if(a>50){
5| resolve(a);
6| }else{
7| reject(a);
8| }
9| })
10| .then((value)=>{
11| console.log("随机数的值大于50");
12| if(value>75){
13| return true;
14| }else{
15| return new Promise((resolve,reject)=>{
16| reject(value);
17| })
18| }
19| })
20| .then((value)=>{
21| console.log("随机数的值为大于75");
22| })
23| .catch((value)=>{
24| console.log("随机数的值为:"+ value);
25| })
---------------------------------------------------------------------------------
/*
解析:
当随机数小于等于50:
执行第7行: reject(a)
由于.then中没有失败的回调,继续往下执行,
直到找到.catch,执行catch中的回调
如果没有.catch,则会将失败结果抛出
控制台显示:
随机数的值为:xxxxxxxx
当随机数小于等于75,大于50
执行第5行:resolve(a)
再执行第16行
因为第一个.then 方法return的是Promise对象,并且状态为失败
又因为第二个.then 方法没有失败的回调,继续往下执行,
直到找到.catch,执行catch中的回调
控制台显示:
随机数的值大于50
随机数的值为:xxxxxxxx
当随机数大于75:
执行第5行:resolve(a)
进行第一个.then中的成功的回调,
执行第13行,return 的结果是 非promise类型的值
所以第一个.then 的状态为成功,
执行第二个.then中的成功的回调
控制台显示:
随机数的值大于50
随机数的值为大于75
*/