认识Promise
什么是Promise?
Promise是异步编程的一种解决方案。
什么时候会处理异步事件呢?
很常见的场景就是网络请求了,封装一个网络请求的函数时,不能立即得到结果,往往会传入另一个函数,在请求成功后,将数据通过传入的函数回调出去。
但是当网络请求非常复杂时,就会出现回调地狱
网络请求的回调地狱
比如下面的场景:
- 通过url1,获取数据data1,data1中包含下一个请求的url2
- 通过data1取出url2,获取数据data2,data2中包含下一个请求的url3
- 通过data2取出url3,获取数据data3,data3中包含下一个请求的url4
- 通过data3取出url4,获取到最终的数据data4

上面的代码,正常情况下,不会有问题,可以正常运行并得到最终数据
但是,这样的代码不仅难看,还不利于维护,简直像地狱
这时,就希望有一种优雅的方式来进行这种异步操作
如何做呢?就是使用Promise,它可以以一种非常优雅的方式来解决这个问题
Promise的基本使用
定时器的异步事件
用定时器模拟异步事件:
- 假设data是从网络请求得到的数据
- console.log是处理方式

换成Promise代码

这个例子看上去就感觉是多此一举,没必要,首先,Promise的代码明显比上面的代码复杂,其次,Promise代码中又包含resolve、reject、then、catch,这又是什么东西呢?
定时器异步事件解析
读一读上面的代码到底做了什么?
- new Promise很明显是创建了一个Promise对象
- 小括号中 ((resolve, reject) => {}),也很明显是一个函数
- resolve和reject它们也是函数,通常情况下,会根据请求数据的成功和失败来决定调用哪一个
- 如果成功,调用resolve(message),后续的then会被回调
- 如果失败,调用reject(error),后续的catch会被回调
Promise的三种状态

- pending:等待状态,比如正在进行网络请求,或者定时器没到时间
- fulfill:满足状态,当主动回调resolve时,就处于该状态,并且回调 .then()
- reject:拒绝状态,当主动回调reject时,就处于该状态,并且回调 .catch()
Promise的另外处理形式:
不使用.catch(),在 .then() 中,使用两个函数,第一个为resolve回调,第二个为reject回调

Promise的链式调用
无论是then还是catch都可以返回一个Promise对象,所以,代码可以进行链式调用
需求:
- 网络请求: aaa -> 自己处理(10行)
-
处理:aaa111 -> 自己处理(10行)
-
处理:aaa111222 -> 自己处理
new Promise((resolve, reject) => {
setTimeout(() => {
resolve("aaa");
}, 1000);
})
.then((res) => {
// 1.自己处理10行代码
console.log(res, "第一层处理的10行代码");
// 2.对结果进行第一次处理
return new Promise((resolve) => {
resolve(res + "111");
});
})
.then((res) => {
console.log(res, "第二层处理的10行代码");
return new Promise((resolve) => {
resolve(res + "222");
});
})
.then((res) => {
console.log(res, "第三层处理的10行代码");
});
new Promise(resolve => resolve(结果))简写
new Promise((resolve, reject) => {
setTimeout(() => {
resolve("aaa");
}, 1000);
})
.then((res) => {
// 1.自己处理10行代码
console.log(res, "第一层处理的10行代码");
// 2.对结果进行第一次处理
return Promise.resolve(res + "111");
})
.then((res) => {
console.log(res, "第二层处理的10行代码");
return Promise.resolve(res + "222");
})
.then((res) => {
console.log(res, "第三层处理的10行代码");
});
省略掉Promise.resolve
new Promise((resolve, reject) => {
setTimeout(() => {
resolve("aaa");
}, 1000);
})
.then((res) => {
// 1.自己处理10行代码
console.log(res, "第一层处理的10行代码");
// 2.对结果进行第一次处理
return res + "111";
})
.then((res) => {
console.log(res, "第二层处理的10行代码");
return res + "222";
})
.then((res) => {
console.log(res, "第三层处理的10行代码");
});
在进行第一层处理后,返回错误
new Promise((resolve, reject) => {
setTimeout(() => {
resolve("aaa");
}, 1000);
})
.then((res) => {
// 1.自己处理10行代码
console.log(res, "第一层处理的10行代码");
// 2.对结果进行第一次处理
// 方法一:
// return Promise.reject("error");
// 方法二:
throw "error";
})
.then((res) => {
console.log(res, "第二层处理的10行代码");
return Promise.resolve(res + "222");
})
.then((res) => {
console.log(res, "第三层处理的10行代码");
})
.catch((err) => {
console.log(err);
});
Promise的all方法使用
当某个需求需要两个请求都完成后执行回调函数
传统ajax方法:

使用Promise.all方法

使用定时器模拟
Promise.all([
new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ name: "xiaoming", age: 18 });
}, 2000);
}),
new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ name: "xiaohong", age: 16 });
}, 1000);
}),
]).then((results) => {
console.log(results);
});
最终结果:

Promise是JavaScript中处理异步操作的重要工具,它解决了回调地狱的问题,提供了链式调用和错误处理的优雅方式。本文详细介绍了Promise的基本概念、状态转换、链式调用以及Promise.all方法的使用,帮助开发者更好地理解和运用Promise进行复杂异步任务的管理。

1593

被折叠的 条评论
为什么被折叠?



