ES6教程 从入门快速掌握ES6新特性 精讲(四) 一文看懂!

2020-11-13  本文已影响0人  TylerOu

ES6教程 从入门快速掌握ES6新特性 精讲(四) 一文看懂!

这个是博主新开的一个坑,其目的是为了帮己帮人更好地学习ES6。
博主会通过抛出疑问,然后举一个具有代表性的证明且容易理解例子的方法来学习。
希望能够帮助到你们快速掌握ES6。
喜欢的话请给个关注或者点个赞再走吧,你们的支持是我创作的动力!

附:
【ES6教程】快速掌握ES6新特性(一)
【ES6教程】快速掌握ES6新特性(二)
【ES6教程】快速掌握ES6新特性(三)

一、Promise对象

1、含义

Promise为ES6提出的实现异步请求的对象。其特点如下两点:

(1)Promise对象状态不受外界影响。Promise对象有三种状态,分别为
pending(等待态)、fulfilled(成功态)、和rejected(失败态)。只有Promise对象在进行异步操作时才能决定该状态。其他均不能影响Promise当前的状态。

(2)Promise状态一旦改变后,就处于不可变状态。 Promise状态的转变只有两种一是从pending(等待态)到fulfilled(成功态),第二为从pending(等待态)到rejected(失败态),一旦发生状态转变后,以后均是这个转变状态,即该状态已定型(resolved),以后不能再发生改变。

假设在进行异步操作时,Promise的状态从pending到fulfilled,一旦错过,再去监听Promise对象,是得不到结果的。

Promise对象的优缺点如下:
优点:相比如ES6前,开启异步操作,常需要嵌套大量的函数,导致整个异步操作的结构体繁琐复杂。而Promise对象开启异步则可简洁异步操作。

缺点:Promise对象一旦创建后就会立即执行且不能中途取消。其次,如果不设置回调函数,Promise内部的异常则不会抛出到外部。(回调函数的设置具体看下面语法)

Ps: 如果某些事件不断地反复发生,一般来说,使用 Stream 模式是比部署Promise更好的选择。

2、基本用法

语法如下:

# 一、 创建:使用构造函数创建实例
let promise = new Promise();

# 二、参数说明 
# new Promise(function(resolve, reject){code.....});
# Promise构造函数接受一个函数作为参数
# 该函数的两个参数resolve和reject为JavaScript部署,不用手动配置。表现实际为两个函数
# resolve() 为 Promise状态从pending到resolved时调用,即异步操作成功后调用。
# 并将异步操作成功结果,通过 resolve(value)中传出
# rejectd() 为Promise状态从pending状态到rejected时调用,即异步操作失败后调用。
# 并将异步操作失败的结果,通过 rejecet(error)中传出

代码段如下:
let promise = new Promise(function(resolve,reject){
    if(/*异步操作成功*/){
        //该value传入回调函数中
        resolve(value);
    }else{
        //该error传入回调函数
        reject(error);
    }
})


3、实例方法 then( )

Promise对象的回调函数 then( )
语法如下:

# Promise对象的回调函数
# Promise对象的实例生成后,可以通过 then()方法创建回调函数
# 参数说明 then(function(value),...function(error)) 
# 通过 then()函数可以分别指定处理resolve状态的回调函数和reject状态的回调函数
# 注意:then() 为异步方法体

代码段如下:

let promise = new Promise(function (resolve, reject) {
      //promise对象一旦创建后就会立马触发
      //......同步方法体
      console.log(" Promise对象同步方法体");
      setTimeout(() => {
        console.log("在Promise对象同步方法体中异步方法体");
      }, 3000);
      
      //调用resolve的回调函数 
      resolve('异步');
});

promise.then(function (value) {
    //异步方法体
   console.log('Promise对象'+value+"方法体的回调函数");
});
console.log("全文同步方法体");

输出顺序为: 
Promise对象同步方法体 =》 
全文同步方法体 =》
Promise对象异步方法体的回调函数=》
在Promise对象同步方法体中异步方法体

PS:Promsise对象回调函数的优先级高于Promise对象同步方法体中开启的异步函数。


4、实例方法 catch( )

用于指定Promise对象中任何异常错误的回调函数。

语法如下:

# 创建 catch()
let promise = new Promise(function(){});
promise.then(function(){})
.catch(function(){..捕捉整个Promise对象的异常..})

5、实例方法 finally( )

不管Promise状态如何发生变化,最终都会执行的函数finally( )

语法如下:

# 创建
let promise = new Promise(function(){});
promise.then(function(){})
.catch(function(error){..捕捉整个Promise对象的异常..})
.finally(function(){...最终执行的代码段})

# Ps:finally()方法的函数不接受任何的参数

6、对象方法 all( )

方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

# 一、创建 
let promiseAll  = Promise.all([xx,xx,xx]);

# 二、参数说明
# Promise.all([p1,p2,p3])
# all方法可以接受多个参数,但每个参数都必须是一个Promise对象
# 如果其中有一个不为Promise对象,即会调用Promise.resolve转换为Promise对象
# 参数一般为成员以promise为对象组成的数组
# 也可不为数组,但其参数必须是iterable接口的数据结构和其成员必须是promise对象

代码片段如下:
let promiseAll = Promise.all([p1,p2,p3])

# 三、本身使用Promise.all为一个组合的Prosmise实例
# 它可以拥有 then()、catch()、finally( )等方法
# let promiseAll = Promise.all([p1,p2,p3]).then().catch().finally()

# 四、实例方法执行规则
# 其由Promsise.all()创建出来的Promise对象的实例方法执行规则如下:
let p = Promise.all([p1,p2,p3]).then().catch().finally()
# Promise.all().then() 方法
第一种情况:当p1,p2,p3的状态均达fulfilled后,p的状态才为fulfilled。
此时将返回一个由p1,p2,p3返回值组成的数组,到p的 then() 回调函数上。

第二种情况:当p1....p3只要有一个对象为rejected状态,p的状态就变为rejected,
此时p1....p3中第一个状态为reject的对象,其返回值将传入到 then( )中

注意:某一个实例状态发生错误 但 “能被其自身catch( )及时处理” 时,其状态不会处理成reject。
其状态也会被处理成resolve。

第三种情况:当p1....p3其中一个为实例发生reject错误时,如果能被及时处理成定型resolve状态,
此时将同样地返回一个由p1,p2,p3返回值组成的数组,到p的 then() 的回调函数上。

第三种情况 举例说明:

const p1 = new Promise((resolve, reject) => {
  resolve('hello');
})
.then(resolve => resolve)
.catch(e => e);

const p2 = new Promise((resolve, reject) => {
  throw new Error('报错了');
})
.then(resolve => resolve)
.catch(e => e);

Promise.all([p1, p2])
.then(result => console.log(result)) //['hello world',Error]
.catch(e => console.log(e));


上面代码中:p1的状态从 pedding 到 fulfilled,最终resolve(定型)。返回值为回调函数的结果。
           p2的状态从 pedding 到 rejected,但由于被其自身的 catch() 方法及时处理错误,最终也为成功的resolve(定型)状态。
           返回值为catch()函数返回的结果。       
           最后将p1,p2放入Promise.all( )中组成混合实例。由于p1,p2均为resolve状态,所以调用其自身的 then() 函数返回,以P1,P2返回值作为成员的数组。
           ['hello world',Error]
      
# Promise.all().then().catch()
catch()用于捕抓Promise.all()的异常。例子如上。
须十分注意的是,如果Promise.all( )的实例上,已经定义了catch()方法。
如上述p1,p2.则本身的Promise.all().then().catch()就不会再次调用.

7、对象方法 race( )

Promise.race( )方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

与Promise.all( )方法不同的是,Promise.race( ) 方法参数中一个实例的状态发生变化,自身就率先跟着发生同样的状态变化。参数率先改变状态实例返回值传入到Promise.race( ).then(xxx) 中。

# p1和p2的初始状态都为pedding
# 第一种情况:假设p1在3秒内请求数据成功,状态从pedding到fulfilled,最终resolve。
# 即p2处于pedding时,p1的状态率先发生改变。p也跟着改变,其p1的返回值会传入到p的回调函数 then() 中

# 第二种情况:假设p1在3秒内没有请求数据成功,p2定时器成功调用完毕
# p2状态从pedding到rejected,最终resolve。则p也会跟随p2的状态。
# 由于p2没有定义自身的catch()处理函数,最终将p2返回结果Error对象传到Promise.race().then().catch()上。由catch()进行处理。

let p1 = new Promise(function (resolve, reject) {
  resolve("p1请求数据");
});
p1.then((resolve) => resolve);

let p2 = new Promise(function (resolve, reject) {
  setTimeout(() => reject(new Error('请求超时')), 3000);
});
p2.then((resolve) => resolve);

let p = Promise.race([p1, p2]);
p.then(result => console.log(result)); //第一种情况:p1请求数据
p.catch(result=>console.log(result); //第二种情况:Error:请求超时

上一篇下一篇

猜你喜欢

热点阅读