ES6教程 从入门快速掌握ES6新特性 精讲(四) 一文看懂!
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:请求超时