为什么需要Promise
需求
通过ajax请求id,再通过id请求用户名,再根据用户名获取email
回调地狱
在回调函数中嵌套回调。 Promise为解决回调地狱而出现。
Promise
Promise是一个构造函数,通过new关键字实例化对象。
语法
new Promise((resolve, reject) => {})
- Promise接受一个函数作为参数
- 在参数函数重接受两个参数
- reslove
- reject
Promise实例有两个属性
- state: 状态
- result: 结果
Promise的状态
- pending: 准备、待解决、进行中
- fulfilled: 已完成、成功
- rejected: 已拒绝、失败
Promise状态的改变
通过调用resolve()和reject()改变当前Promise对象的状态。
Promise状态的改变是一次性的。
const p = new Promise((resolve, reject) => {
// resolve(): 调用函数,使当前Promise对象的状态改成fullfilled
resolve('success');
// reject(): 调用函数,使当前Promise对象的状态改成rejected
reject('error');
})
console.dir(p);
Promise结果
const p = new Promise((resolve, reject) => {
// 通过调用resolve,传递参数,改变当前Promise实例的结果
// resolve('成功的结果');
reject('失败的结果');
});
console.dir(p);
Promise方法
then方法
在then方法的参数函数中,通过形参使用Promise对象的结果。
then方法返回一个新的Promise实例,状态是pending。
const p = new Promise((resolve, reject) => {
resolve('张三');
// reject('参数error')
})
// then(函数, 函数): Promise对象
const t = p.then((value) => {
// 当Promise的状态是fulfilled时执行
console.log(value);
}, (reason) => {
// 当Promise的状态是rejected时执行
console.log('error',reason);
})
console.dir(t);
Promise的状态不改变,then里的方法不会执行。
new Promise((resolve, reject) =>{
})
.then((value) => {
console.log('成功');
}, (reason) => {
console.log('失败');
})
在then方法中,通过return将返回的Promise实例改为fulfilled状态。
在then方法中,代码出错,返回的Promise实例的状态变为rejected。
new Promise((resolve, reject) =>{
resolve();
})
.then((value) => {
console.log('成功');
// 使用return可以将返回的Promise实例的状态改成fulfilled
// return 123;
// 如果这块的代码出错,会将返回的Promise实例的状态改为rejected
console.log(a);
}, (reason) => {
console.log('失败');
})
.then((result) =>{
console.log('执行到这', result);
}, (error) => {
console.log('报错了', error);
})
catch方法
const p = new Promise((resolve, reject) => {
// reject(); // console.log(a);
throw new Error('出错了');
})
// catch中的参数函数的执行时机
// 1. 当Promise的状态改为rejected时被执行
// 2. 当Promise执行体中出现代码错误时被执行
p.catch((reason) => {
console.log('失败了', reason);
})
Promise解决回调地狱
function getData(url, data = {}) {
return new Promise((resolve, reject) => {
$.ajax({
type: 'GET',
url: url,
data: data,
success: function(res) {
resolve(res);
},
error: function(res) {
reject(res);
}
})
})
}
getData('./assets/data1.json')
.then((data) => {
const { id } = data;
return getData('./assets/data2.json', { id }).then((data) => {
const { username } = data;
return getData('./assets/data3.json', { username })
.then((data) => {
console.log(data);
})
})
})