1. Promise 是用来干嘛的?
解决回调地狱的问题
2. 什么是回调地狱?
回调函数里面嵌套回调函数
eg:
$.ajax({
type: 'GET',
url: './data1.json',
success: function (res) {
const { id } = res
console.log(id);
$.ajax({
type: 'GET',
url: './data2.json',
data: { id },
success: function (res) {
const { username } = res
$.ajax({
type: 'GET',
url: './data3.json',
data: { username },
success: function (res) {
const { username } = res
}
})
}
})
}
})
3. Promise 的语法
new Promise((resolve,reject)=>{
})
4. Promise 的状态
pending 等待
fulfilled 成功
rejected 失败
5. Promise 的结果
const p = new Promise((resolve, reject) => {
// 成功时调用 resolve
resolve("成功的值");
// 失败时调用 reject
reject("失败的原因");
});
6. then 方法
new Promise((resolve,reject)=>{
}).then((value)=>{
console.log("成功时调用",value)
},(reason)=>{
console.log("失败时调用",reason)
})
6.1 形参
value ,resolve () 函数传入的实参会传给 value
reason, reject ()函数传入的实参会传给 reason
6.2返回值
then 方法的返回值是一个新的 Promise 对象
then 的回调函数中,return 一个普通值时,新的 Promise 状态会由 pending 变为 fulfilled,该值会传给下一个 .then。
如果 return 的是一个新的 Promise,则下一个 .then 会等待这个 Promise 执行完,再拿到它的结果。
7. catch 方法
catch(fn) 本质上是 then(null, fn) 的语法糖then 的第二个参数只能捕获 Promise 本身 的 reject,捕获不了同一个 then 的第一个函数里抛出的错误。而 catch 挂在链式末尾,前面任何环节出错都能兜住。
// ❌ 用 then 第二个参数的问题
p.then(
() => { throw new Error("then里出错了") },
err => { /* 这里捕获不到上面的错误! */ }
);
// ✅ 用 catch 更安全
p.then(() => {
throw new Error("then里出错了");
}).catch(err => {
// 这里能捕获到 ✔
});
8. 解决回调地狱问题
new Promise((resolve, reject) => {
$.ajax({
type: 'GET',
url: './data1.json',
success: function (res) {
resolve(res)
},
error: function (res) {
reject(res)
}
})
}).then((data) => {
// console.log(data);
const { id } = data
return new Promise((resolve, reject) => {
$.ajax({
type: "GET",
url: './data2.json',
data: { id },
success: function (res) {
resolve(res)
},
error: function (res) {
reject(res)
}
})
}).then((data) => {
const { username } = data
return new Promise((resolve, reject) => {
$.ajax({
type: "GET",
url: './data3.json',
data: { username },
success: function (res) {
console.log(res)
},
error: function (res) {
}
})
})
})
})
将重复的 new Promise + $.ajax 封装成 getData 函数,避免代码冗余,也让链式调用更简洁易读。
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('data1.json')
.then((data) => {
const { id } = data
return getData('data2.json', { id })
})
.then((data) => {
const { username } = data
return getData('data3.json', { username })
})
.then((data) => {
console.log(data);
})