Promise中的then方法详解

Promise详解

/* 
 *  创建Promise实例的时候得传一个函数 executor,并且这个函数接收两个参数
      + resolve函数:将实例的状态从 pending 修改为 fulfilled/resolved,同时将实例的值改为执行这个函数时传递的实参

      + reject函数:将实例的状态从 pending 修改为 rejected,同时将实例的值改为执行这个函数时传递的实参

    每一个Promise实例都有两个重要的属性:
      + [[PromiseState]] 实例的状态
        + pending  初始状态
          + 通过new创建实例的时候,没有在executor函数中执行resolve函数,也没有执行reject函数,则创建的实例状态为pending,值为undefined
          + 通过 实例1.then() 执行then函数时,没有给then函数传递A函数和B函数,则返回的新实例的状态为pending,值为实例1的结果

        + fulfilled/resolved  成功状态
        + rejected  失败状态

      注意:实例的状态是单向改变的,即只能从pending变为fulfilled/resolved,或者从pending变为rejected

      + [[PromiseResult]] 实例的结果/值
        + undefined 初始值
        + 成功的结果/失败的原因
*/

let p1 = new Promise((resolve, reject) => {
  resolve(100);
  reject(200); // 这里不会执行,因为执行完 resolve(100) 后实例的状态已经从pending改为fulfilled了
});
console.dir(p1); // 状态为 fulfilled,值为 100 
/* 
 * 实例可以调用其所属类的原型上的方法,Promise也一样

 * Promise.prototype上的方法:
    + then(A, B):then方法跟executor函数一样,接收两个函数 A和B
      + A(res)函数:
        接收一个参数res,如果当前实例的状态为 fulfilled/resolved 则执行它,且 res 的值为当前实例的结果/值

      + B(rej)函数:
        接收一个参数 rej,如果当前实例的状态为 rejected 则执行它,且 rej 的值为实例的结果/值

    + catch
    + finally
*/
let p1 = new Promise((resolve, reject) => {
  resolve(100);
});
let p2 = p1.then(res=>{
  console.log(res); // 100
}, rej=>{
  console.log(rej)
}); 

// 通过 实例.then() 执行then方法之后会返回一个新的 Promise 实例
 console.log(p2);  //一个新的实例
/* 
 * 执行 实例1.then 函数返回一个新的实例,新的实例2的状态和值怎么确定?
    + 实例2的状态:
      1、如果在执行时没有给then传递A函数和B函数,那实例2的状态为pending
      2、实例1.then(A,B);不论then中执行的是A函数还是B函数,只要不报错,那实例2的状态就为 fulfilled;如果报错,实例2的状态则为 rejected
    
    + 实例2的结果/值
      1、如果实例2的状态为 pending,则实例2的值跟实例1的一样
      2、如果实例2的状态为 fulfilled/resolved,那实例2的值是实例1基于then函数中执行A或执行B返回的结果
        特殊情况:如果函数A或者函数B中返回的是一个新的Promise实例,那return的实例的状态以及结果,直接决定实例2的状态和结果
      3、如果实例2的状态为 rejected,那实例2的结果/值就是失败的原因
  
  实例1的状态和值也受 executor 函数执行的影响
    + 如果执行 executor 函数报错了,则实例的是状态为 rejected,值为报错的原因
    + 如果执行 executor 函数没有报错,那要看executor函数中执行的是 resolev函数还是rejecte函数
*/
 let p1 = new Promise((resolve, reject) => {
  resolve(100);
  reject(200); // 这里不会执行,因为执行完 resolve(100) 后实例的状态已经从pending改为fulfilled了
});
console.dir(p1); // 状态为 fulfilled,值为 100

let p2 = p1.then(res=>{
  // return 400;  // 实例p2的状态为 fulfilled,值为 400

  // 返回一个状态为pending,值为undefined的实例
  return new Promise(()=>{}); // p2的状态为 pending,值为undefined
}, rej=>{

}); 
/* 
 * Promise作为内置类,也是一个对象,也有自己的私有方法(只能通过Promise.xxx()调用)
    + resolve([val]):快速创建一个状态为成功,值为val的实例
    + rejecte([val]):快速创建一个状态为失败,值为val的实例
    + all():
    + race():
*/
 let p1 = Promise.resolve(100); // p1的状态为 fulfilled,值为 100

 let p2 = Promise.reject(400); // p2的状态为 rejected,值为 400
/* 
 * then([A],[B]):如果其中一个函数没有传递,则会“顺延”
    + [A]没有传递:则找下一个 then 中的 A 函数
    + [B]没有传递:则找下一个 then 中的 B 函数
*/

// 成功的顺延:如果then中没有传A函数,默认会执行 res=>{return res}
 Promise.resolve(200).then(null/!* res =>{return res} *!/, rej=>{
  console.log('我是第一个then中的B函数')
}).then(res=>{
  console.log('我是第二个then中的A函数', res)
}, rej=>{
  console.log('我是第二个then中的B函数', rej);// 404
}); 

// 失败的顺延:如果then中没有传B函数,默认会执行 rej=>{return Promise.reject(rej)}
 Promise.reject(404).then(res=>{
  console.log('第一个then中的A函数', res)
},/!* rej=>{return Promise.reject(rej)} *!/).then(res=>{
  console.log('我是第二个then中的A函数', res)
}, rej=>{
  console.log('我是第二个then中的B函数', rej);// 404
}); 


//  catch:等价于 then(null,rej=>{...})
Promise.reject(10).then(res=>{
  console.log('成功了', res)
}).then(res=>{
  console.log('我是第二个then')
}).catch(rej =>{
  console.log('失败了', rej); // 输出  10
});

// 真实项目中:then只是处理成功,即只传一个A函数;catch处理失败(传B函数),且通常将catch写在末尾

// 返回失败状态的实例,但是没有做失败处理,浏览器控制台有报错(但是不影响其他代码的执行)
/* Promise.reject(10).then(res=>{
  console.log(res)
}); // 浏览器中会有报错 */

// 如果加上catch,哪怕什么都不做,浏览器也不报错了
Promise.reject(10).then(res=>{
  console.log('成功');
}).catch(rej=>{});  // 不报错了

你可能感兴趣的:(javaScript学习,javascript,js)