ES6-Promise的理解
Promise介绍
Promise是ES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
- Promise 构造函数: Promise (excutor) {}
- Promise.prototype.then 方法
- Promise.prototype.catch 方法
Promise的特点
1、对象的状态不受外界影响。Promise
对象代表一个异步操作,有三种状态:pending
(进行中)、fulfilled
(已成功)和rejected
(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
2、状态只能由 Pending 变为 Fulfilled 或由 Pending 变为 Rejected,且状态改变之后不会在发生变化,会一直保持这个状态。
3、Pending 变为 Fulfilled 会得到一个私有value,Pending 变为 Rejected会得到一个私有reason,当Promise达到了Fulfilled或Rejected时,执行的异步代码会接收到这个value或reason。
Promise的基本语法
// 实例化Promise对象
let p = new Promise(function (resolve, reject) {
// 使用定时器模拟异步操作
setTimeout(function () {
// 请求成功调用resolve
let data = '数据库中的数据';
resolve(data);
// 请求失败调用resolve
let err = '数据读取失败';
reject(err);
}, 2000);
})
// 调用promise对象中的then方法
/*
then方法接受两个参数,两个参数都是函数类型的值
成功的形参一般叫做value
失败的形参一般叫做reason
*/
p.then(function (value) {
console.log(value);
}, function (reason) {
console.error(reason);
})
使用promise封装Ajax
//接口地址 https://cnodejs.org/api/v1/topics
let p = new Promise((resolve, reject) => {
// 1. 创建对象
let xhr = new XMLHttpRequest();
// 2. 初始化
xhr.open('get', 'https://cnodejs.org/api/v1/topics')
// 3.发送
xhr.send();
// 4.绑定事件
xhr.onreadystatechange = function () {
// 判断
if (xhr.readyState === 4) {
// 判断响应状态码 200 - 300
if (xhr.status >= 200 & xhr.status < 300) {
// 表示成功
resolve(xhr.response);
} else {
// 如果失败
reject(xhr.status);
}
}
}
})
// 指定回调
p.then(function (value) {
console.log(value);
}, function (reason) {
console.error(reason);
})
Promise.prototype.then方法
then() 接受两个回调函数作为参数。当 Promise
执行的内容符合成功条件时,调用resolve
函数,失败就调用 reject
函数。其中第二个参数可以省略(catch()方法的作用),then
方法返回的是一个新的 Promise
实例,因此可以链式调用。
// 创建Promis对象
let p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('用户数据');
// reject('出错了');
},1000)
});
// 调用then方法 then方法返回结果是Promise对象,对象状态由回调函数的执行结果决定
// 1.如果函数中返回的结果是非promise类型的属性,状态为成功,返回值为对象的的成功的值
let result = p.then(value=>{
console.log(value);
//return 123;// 状态为成功,返回值为对象的的成功的值123
},reason =>{
console.warn(reason);
});
console.log(result);
Promise.prototype.then()
Promise
实例具有then
方法,也就是说,then
方法是定义在原型对象上Promise.prototype
上的,它的作用是为Promise
实例添加状态改变时的回调函数。then
方法的第一个参数是resolved
状态的回调函数,第二个参数(可选)是rejected
状态的回调函数。
then
方法返回的结果也是是一个Promise
实例(注意,then方法返回的结果是由回调函数的执行结果来决定的)。
回调函数结果是非promise类型的属性时
let result = p.then(value=>{
console.log(value);
//非Promise类型的属性,返回值为对象的的成功的值
return 'hello';
},reason =>{
console.warn(reason);
});
console.log(result);
回调函数返回的结果是promise类型的数据时
let result = p.then(value=>{
console.log(value);
//是Promise对象,内部的返回的promise的状态就决定then方法返回promise的状态
return new Promise((resolve,reject)=>{
resolve('ok'); //这里返回成功,then方法返回的也是成功的状态,返回失败,then方法也是返回失败的状态
});
},reason =>{
console.warn(reason);
});
console.log(result);
抛出错误
let result = p.then(value=>{
console.log(value);
throw new Error('出错啦');// 抛出错误
},reason =>{
console.warn(reason);
});
console.log(result);
抛出错误,这个状态还是错误的状态,错误的值是抛出来的值
Promise.prototype.catch 方法
catch() 该方法相当于then
方法的第二个参数,指向reject
的回调函数;还有一个作用是在执行resolve
回调函数时,如果出现错误,抛出异常,不会停止运行,而是进入catch
方法中。
const p = new Promise((resolve, reject)=>{
setTimeout(()=>{
//设置 p 对象的状态为失败, 并设置失败的值
reject("出错啦!");
}, 1000)
});
// p.then(function(value){}, function(reason){
// console.error(reason);
// });
p.catch(function(reason){
console.warn(reason);
});
Promise.all() 方法
all()方法可以完成并行任务, 它接收一个数组,数组的每一项都是一个 promise
对象。当数组中所有的 promise
的状态都达到 resolved
的时候,all
方法的状态就会变成 resolved
,如果有一个状态变成了 rejected
,那么 all
方法的状态就会变成 rejected
。
let promise1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(1);
},2000)
});
let promise2 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(2);
},1000)
});
Promise.all([promise1,promise2]).then(res=>{
console.log(res); //[1,2]
})
Promise.race() 方法
race() 接受的参数也是一个每项都是 promise
的数组,当最先执行完的事件执行完之后,就直接返回该 promise
对象的值。如果第一个 promise
对象状态变成 resolved
,那promise最终的状态就变成了resolved
;反之第一个 promise
变成 rejected
,那最终的状态就会变成 rejected
。
let promise1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
reject(1);
},2000)
});
let promise2 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(2);
},1000)
});
Promise.race([promise1,promise2]).then(res=>{
console.log(res);
//结果:2
},rej=>{
console.log(rej)};
)
Promise.prototype.finally() 方法
finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});