update: promise

This commit is contained in:
qianguyihao
2021-05-17 17:59:58 +08:00
parent 4b2ef2d764
commit b34943e616
2 changed files with 68 additions and 44 deletions

View File

@@ -1,5 +1,3 @@
## 为什么需要 Promise
我们在上一篇文章单线程和异步中讲过Javascript 单线程语早期我们解决异步场景时部分情况都是通过回调函数来进
@@ -8,7 +6,7 @@
### 回调的定义
把函数A传给另一个函数B调用那么函数A就是回调函数
把函数 A 传给另一个函数 B 调用那么函数 A 就是回调函数
例如在浏览器中发送 ajax 请求就是常个异步场景发送请求后需要等待一段时间等服务端响应之后我们才能拿到结果如果我们希望在异步结束之后执某个操作就只能通过**回调函数**这样的式进操作
@@ -26,22 +24,31 @@ dynamicFunc(function () {
例如上这个例dynamicFunc 就是个异步函数 setTimeout 会在 1s 之后调 callback 函数按照上的调最终 1s 之后会打印 qian gu 这个结果
为了能使回调函数以更优雅的式进 ES6 语法中新增了个名为 Promise 的新规范
### 回调的缺点
回调的写法比较直观不需要 return层层嵌套即可但也存在两个问题
- 1如果嵌套过深则会出现**回调地狱**的问题
- 1如果嵌套过深则会出现**回调地狱**的问题
- 2不同的函数回调的参数在写法上可能不一致导致不规范且需要**单独记忆**
- 2不同的函数回调的参数在写法上可能不一致导致不规范且需要**单独记忆**
我们来具体看看这两个问题
**1回调地狱的问题**
如果后续还有内容需要在异步函数结束时输出就需要多个异步函数进嵌套常不利于后续的维护而且会导致**回调地狱**的问题
如果多个异步函数存在依赖关系比如需要等第一个异步函数执行完成后才能执行第二个异步函数等第二个异步函数执行完毕后才能执行第三个异步函数就需要多个异步函数进层层嵌套常不利于后续的维护而且会导致**回调地狱**的问题
关于回调地狱我们来举一个形象的例子
> 假设买菜做饭洗碗倒厨余垃圾都是异步的
> 但真实的场景中实际的操作流程是买菜成功之后才能开始做饭做饭成功后才能开始洗碗洗碗完成后 再倒厨余垃圾这里的一系列动作就涉及到了多层嵌套调用也就是回调地狱
关于回调地狱我们来看看两段代码
定时器的代码举例
```js
setTimeout(function () {
@@ -55,13 +62,20 @@ setTimeout(function () {
}, 1000);
```
关于回调地狱我们来举一个形象的例子
ajax 请求的代码举例
假设买菜做饭洗碗倒厨余垃圾都是异步的
但真实的场景中实际的操作流程是买菜成功之后才能开始做饭做饭成功后才能开始洗碗洗碗完成后 再倒厨余垃圾这里的一系列动作就涉及到了多层嵌套调用也就是回调地狱
ES5 当进行多层嵌套回调时会导致代码层次过多很难进行后续维护和二次开发而且会导致**回调地狱**的问题ES6 中的 Promise 就可以解决这两个问题
```js
// 伪代码
ajax('a.json', (res1) => {
console.log(res1);
ajax('b.json', (res2) => {
console.log(res2);
ajax('c.json', (res3) => {
console.log(res3);
});
});
});
```
**2回调的写法不一致问题**
@@ -73,8 +87,7 @@ readFile('d:\\readme.text', function (error, data) {
} else {
console.log('文件读取成功');
}
})
});
// jQuery的 ajax 写法中,成功回调和失败回调,是通过两个回调函数来区分
$.ajax({
@@ -84,15 +97,17 @@ $.ajax({
},
error: function (err) {
console.log('文件读取失败');
}
})
},
});
```
我们可以看到上面的代码中成功回调和失败回调写法不统一需要单独记忆容易出错
**小结**
ES5 当进行多层嵌套回调时会导致代码层次过多很难进行后续维护和二次开发而且会导致**回调地狱**的问题ES6 中的 Promise 就可以解决这两个问题
当然 Promise 的更强大功能不止于此我们来一探究竟
### Promise 的介绍和优点
ES6 中的 Promise 是异步编程的一种方案从语法上讲Promise 是一个对象它可以获取异步操作的消息
@@ -108,15 +123,21 @@ Promise 的伪代码结构,大概是这样的:
```js
// 伪代码1
myPromise()
.then(function () { }, function () { })
.then(function () { }, function () { })
.then(function () { }, function () { })
.then(
function () {},
function () {}
)
.then(
function () {},
function () {}
)
.then(
function () {},
function () {}
);
// 伪代码2
是时候展现真正的厨艺了()
.然后(买菜)
.然后(做饭)
.然后(洗碗)
是时候展现真正的厨艺了().然后(买菜).然后(做饭).然后(洗碗);
```
上面的伪代码可以看出即便在业务逻辑上是层层嵌套但是代码写法上却十分优雅也没有过多的嵌套
@@ -131,6 +152,8 @@ myPromise()
3通过 promise.then() 处理返回结果这里的 `promise` 指的是 Promise 实例
Promise的精髓在于**对异步操作的状态管理**
接下来我们来具体看看 promise 的代码是怎么写的
### Promise 处理异步任务的过程
@@ -259,9 +282,7 @@ try-catch 主要用于捕获异常,注意,这里的异常是指**同步**函
原因是当异步函数抛出异常时对于宏任务而言执行函数时已经将该函数推入栈此时并不在 try-catch 所在的栈所以 try-catch 并不能捕获到错误对于微任务而言比如 promisepromise 的构造函数的异常只能被自带的 reject 也就是.catch 函数捕获到
2写法1中`promiseA().then().catch()``promiseA().catch().then()`区别在于前者可以捕获到 `then` 里面的异常后者不可以
2写法 1 `promiseA().then().catch()``promiseA().catch().then()`区别在于前者可以捕获到 `then` 里面的异常后者不可以
### 小结
@@ -273,16 +294,15 @@ try-catch 主要用于捕获异常,注意,这里的异常是指**同步**函
4失败的 promise后续可以通过 promise 自带的 .catch 法或是 .then 法的第个参数进捕获
## Promise 规范
### Promise 规范解读
Promise 个拥有 then 法的对象或函数任何符合 promise 规范的对象或函数都可以成为 Promise
关于promise 规范的详细解读可以看下面这个链接
关于 promise 规范的详细解读可以看下面这个链接
- Promises/A+ 规范<https://promisesaplus.com/>
- Promises/A+ 规范<https://promisesaplus.com/>
## promise 对象的 3 个状态
@@ -483,8 +503,7 @@ request1()
## 总结
了解这些内容之后 你已经对 Promise 有了基本了解下一篇文章我们来讲一讲 Promise在实战开发的常见用法
了解这些内容之后 你已经对 Promise 有了基本了解下一篇文章我们来讲一讲 Promise 在实战开发的常见用法
## 参考链接