ES6深入认识02

类型转换

Posted by EWL on January 5, 2019
日期 2019-01-05
学习内容 part1. ES6深入认识-promise学习
  part2. React-Router-Dom升级过程记录与学习01

Part01

Promise.prototype.then

Promise.prototype.then方法是Promise原型上的方法,按照书本上的内容,then方法应当有两个参数: resolved以及rejected。前者表示Promise实例在fulfilled状态时的回调函数,后者表示在rejected状态时的回调函数。然而最佳实践则是尽量在then中只写resolved方法,将rejected状态的处理交由catch来负责。

then方法会返回一个新的Promise实例,这为Promise后续的链式调用提供了基础。此外,在then方法中也有存在返回另一个新Promise对象的可能,此时,该then方法后面的一系列回调函数将不再关注最初的Promise对象,而是随着then方法中的新Promise的状态来决定是否调用。

学习示例01:

// 简单的链式调用
let flag = 1;
    let promise = new Promise(function(resolve, reject) {
      console.log('Promise');
      if(flag === 1) {
        resolve();
      } else {
        reject();
      }
    });

    promise.then(function() {
      console.log('resolved in then');
    }).catch(function(err) {
      console.log(err);
    });

学习示例02:

// then方法中返回新的Promise对象
    let flag = 1;
    let flag02 = 1;

    let promise = new Promise(function(resolve, reject) {
      console.log('Promise');
      if(flag === 1) {
        resolve();
      } else {
        reject();
      }
    });

    let promise02 = new Promise(function(resolve, reject) {
      console.log('Promise02');
      if(flag02 === 1) {
        resolve(flag02);
      } else {
        reject('err in promise02');
      }
    });

    promise.then(function() {
      return promise02;
    }).then(function(param) {
      console.log('resolved result in promise02', param);
    }).catch(function(err) {
      console.log(err);
    });

Promise.prototype.catch

Promise.prototype.catch方法也是Promise原型上的方法,它用于捕捉Promise执行链路中抛出的错误,这样的错误来源可能会有以下几种情况:

  • promise中抛出的错误
  • then方法中抛出的错误
  • 当前catch方法之前的catch方法抛出的错误

学习要点

  1. 不在已经执行resolved函数之后去抛出错误,前面的学习中提到promise的状态一旦确定(pending/fulfilled/rejected)就不会再发生变化,所以不会再已经是fulfilled之后仍旧接受rejected状态变化,这样的错误是不会被捕捉的
  2. 在书写resolved/rejected函数时,保证then中书写resolved,catch中书写rejected,这样首先可以保证then里的错误会被后续链式调用的catch捕捉到,又相对符合同步的写法。
  3. catch方法返回的仍旧是一个Promise实例,所以仍旧可以在catch方法后面继续进行链式调用

学习示例如下:

// 不使用catch时,错误总是不能被直接捕捉到
    let flag = 1;
    let flag02 = 1;

    let promise = new Promise(function(resolve, reject) {
      console.log('Promise');
      if(flag === 1) {
        resolve();
      } else {
        reject();
      }
    });

    let promise02 = new Promise(function(resolve, reject) {
      console.log('Promise02');
      if(flag02 === 1) {
        resolve(flag02);
      } else {
        reject('err in promise02');
      }
    });

    promise.then(function() {
      return promise02;
    }).then(function(param) {
      console.log('x', x)
    }, function(err) {
      throw new Error(err);
    });

示例结果如下: image.png

Promise.all

all方法,可以接受多个Promise组成的数组作为参数返回一个总的Promise实例,这么说实际上不够严谨,因为如果该参数不是数组,但是有iterator接口,all也是可以接受的。此外,即使数组成员并非是Promise实例,all也依旧可以使用Promise.resolve将成员们逐个转化为Promise实例。

最终all方法返回的Promise实例的状态时由参数成员决定的,这一点类似于与或非中的与关系,多个成员Promise中有一个是rejected状态的,那么最终的Promise实例就是rejected。如果成员们均为fulfilled状态,那么结果才能是fulfilled。

示例代码如下:

// 成员均为fulfilled状态时
    let flag = 1;
    let flag02 = 1;

    let promise = new Promise(function(resolve, reject) {
      console.log('Promise');
      if(flag === 1) {
        resolve();
      } else {
        reject('err in promise');
      }
    });

    let promise02 = new Promise(function(resolve, reject) {
      console.log('Promise02');
      if(flag02 === 1) {
        resolve(flag02);
      } else {
        reject('err in promise02');
      }
    });
    
    Promise.all([promise, promise02]).then(function() {
      console.log('final promise fulfilled');
    }).catch(function(err) {
      console.log(err);
    });

示例结果如下: image.png