一. 问题:
- 当B请求需要A请求的结果作为参数时, B需要等A有了请求结果之后才能进行请求,
- 如果嵌套着写会造成难以阅读的回调地狱
// 模拟 需要感觉用户名字才能获取用户信息
// 当获取名字比较慢的时候, 则无法继续执行下面的函数
let name;
let info;
function getName() {
setTimeout(() => {
name = '勿悸';
console.log('获取用户名字');
}, 2000)
}
function getInfo() {
setTimeout(() => {
if (name) {
console.log(name);
info = {
age: 17,
sex: 'male',
}
console.log('根据名字获取用户信息');
}
}, 1000)
}
function getAge() {
setTimeout(() => {
if (info) {
console.log(info.age);
console.log('在用户信息找出年龄');
}
}, 1000)
}
getName()
getInfo()
getAge()
// 回调地狱 非常难看懂;
function run() {
setTimeout(() => {
name = '勿悸';
console.log('获取用户名字');
setTimeout(() => {
if (name) {
console.log(name);
info = {
age: 17,
sex: 'male',
}
console.log('根据名字获取用户信息');
setTimeout(() => {
if (info) {
console.log(info.age);
console.log('在用户信息找出年龄');
}
}, 1000)
}
}, 1000)
}, 2000)
}
run()
二. promise使用方法
promise的三个状态 分别是pending(待定), fulfilled(已兑现), rejected(已拒绝).
- pending(待定),执行了executor,状态还在等待中,没有被兑现,也没有被拒绝
- 当promise对象从pending(待定) --> fulfilled(已兑现)时,执行了
resolve回调函数 - 当promise对象从pending(待定) --> rejected(已拒绝)时,执行了
reject回调函数 resolve回调函数由.then传入,reject回调函数由.catch传入
// 模拟是否请求成功
const isSuccess = true;
// 1.此时new出来的promise的状态为等待态(Pending);
const promise = new Promise((resolve, reject) => {
// 2.模拟请求: 当请求结束后promise的状态将转为fulfilled(已兑现)或rejected(已拒绝)
setTimeout(() => {
if (isSuccess) {
resolve('请求成功')
} else {
reject('请求失败')
}
}, 1000);
});
// Promise 有三种状态: 等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected)
// 此时new出来的promise的状态为等待态(Pending);
promise
.then((res) => {
// 3.1 当promise的状态将转为fulfilled(已兑现)时,将执行.then传入的回调函数
console.log(res);
})
.catch((res) => {
// 3.2 当promise的状态将转为或rejected(已拒绝)时,将执行.catch传入的回调函数
console.log(res);
})
三. promise的链式调用
// 模拟是否请求成功
const isSuccess = true;
const promise = new Promise((resolve, reject) => {
// 模拟请求
setTimeout(() => {
if (isSuccess) {
resolve('请求成功')
} else {
reject('请求失败')
}
}, 1000);
});
// 若有一次.then没有执行则跳过接下来的所有then 执行catch
promise
.then((res) => {
console.log(res);
const promise2 = new Promise((resolve, reject) => {
// 模拟请求
setTimeout(() => {
if (isSuccess) {
resolve('第二次请求成功')
} else {
reject('第二次请求失败')
}
}, 1000);
});
return promise2;
})
.then((res) => {
console.log(res);
})
.catch((res) => {
console.log(res);
})
四. 解决问题
// 模拟 需要感觉用户名字才能获取用户信息
// 当获取名字比较慢的时候, 则无法继续执行下面的函数
let name;
let info;
const getName = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
name = '勿悸';
console.log('获取用户名字');
resolve(name)
}, 2000)
})
}
const getInfo = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (name) {
console.log(name);
info = {
age: 17,
sex: 'male',
}
console.log('根据名字获取用户信息');
resolve(info)
}
}, 1000)
})
}
const getAge = () => {
new Promise((resolve, reject) => {
setTimeout(() => {
if (info) {
console.log('在用户信息找出年龄');
resolve(info.age);
}
}, 1000)
})
}
getName()
.then(res => {
return getInfo()
})
.then(res => {
return getAge()
})
五. Promise的静态方法
const promisePending1 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
// 停留在pending(待定)状态的promise1
}, 1000)
})
}
const promisePending2 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
// 停留在pending(待定)状态的promise2
}, 1000)
})
}
const promisePending3 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
// 停留在pending(待定)状态的promise3
}, 1000)
})
}
const promiseResolve1 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('转为fulfilled(已兑现)状态的promise1')
}, 1000)
})
}
const promiseResolve2 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('转为fulfilled(已兑现)状态的promise2')
}, 1000)
})
}
const promiseResolve3 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('转为fulfilled(已兑现)状态的promise3')
}, 1000)
})
}
const promiseReject1 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject('转为rejected(已拒绝)状态的promise1')
}, 1000)
})
}
const promiseReject2 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject('转为rejected(已拒绝)状态的promise2')
}, 1000)
})
}
const promiseReject3 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject('转为rejected(已拒绝)状态的promise3')
}, 1000)
})
}
// .reject()
Promise.reject()
.catch(error => {
console.log('.reject()直接返回一个rejected(已拒绝)状态的promise对象');
})
// .resolve()
Promise.resolve(promisePending1)
.then(res => {
console.log('.resolve()参数传入promise对象, 则直接返回该对象');
})
const obj = {
then: () => {
console.log('.resolve()参数传入一个具有then方法的对象, 会将对象转为promise对象 并立即执行then方法 ');
}
}
Promise.resolve(obj)
Promise.resolve('hello')
.then(res => {
console.log('.resolve()参数传入一个没有then方法的对象或非对象 返回一个状态为fulfilled(已兑现)的promise对象且将参数传入下一个then', res);
})
Promise.resolve()
.then(res => {
console.log('.resolve()不传参数返回一个状态为fulfilled(已兑现)的promise对象');
})
// .all() 全部转为fulfilled(已兑现)
Promise.all([promiseResolve1(), promiseResolve2(), promiseResolve3()])
.then(res => {
console.log('.all()全部转为fulfilled(已兑现)才会调用then方法');
})
Promise.all([promiseResolve1(), promiseResolve2(), promisePending1()])
.finally(res => {
console.log('.all()有任何一个为Pending状态 则依旧为Pending状态');
})
Promise.all([promiseResolve1(), promiseResolve2(), promiseReject1()])
.then(res => {
console.log('.all()有任何一个没转为fulfilled(已兑现)则不执行then方法');
})
.catch(error => {
console.log('.all()有任何一个没转为fulfilled(已兑现) 则执行catch方法, 且只报第一个promise', error);
})
// .allSettled() allSettled()所有的promise都执行了
Promise.allSettled([promiseResolve1(), promiseResolve2(), promisePending1()])
.finally(res => {
console.log('.allSettled()有任何一个为Pending状态 则依旧为Pending状态');
})
Promise.allSettled([promiseResolve1(), promiseResolve2(), promiseReject1()])
.then(res => {
console.log('.allSettled()所有的promise都执行了, 则执行then方法');
})
// .any() 任何一个promise转为fulfilled(已兑现)状态
Promise.any([promiseResolve1(), promiseReject1(), promisePending1()])
.then(res => {
console.log('.any()有任何一个promise转为fulfilled(已兑现)状态 则执行then方法');
})
Promise.any([promiseReject1(), promiseReject2(), promisePending1()])
.finally(res => {
console.log('.any()存在promise为pending 则保持为Pending状态');
})
Promise.any([promiseReject1(), promiseReject2(), promiseReject3()])
.then(res => {
console.log('--------');
})
.catch(res => {
console.log('.any()没有一个转为fulfilled(已兑现)状态且都执行了, 则执行catch');
})
// race() 任何一个promise执行
Promise.race([promiseResolve1(), promisePending1(), promisePending2()])
.then(res => {
console.log('.race()有任何一个promise转为fulfilled(已兑现)或rejected(已拒绝)状态 则执行then方法');
})
Promise.race([promiseReject1(), promisePending1(), promisePending2()])
.then(res => {
console.log('.race()有任何一个promise转为fulfilled(已兑现)或rejected(已拒绝)状态 则执行then方法');
})
.catch(error => {
console.log('.race()有任何一个promise转为rejected(已拒绝)状态 也执行catch方法', error);
})