update: promise

This commit is contained in:
qianguyihao 2021-05-16 18:38:20 +08:00
parent 8dde4b856e
commit a0dd8f9261

View File

@ -1,4 +1,4 @@
## 前言异步和回调 ## 前言异步
### 异步 ### 异步
@ -31,20 +31,17 @@ js 中常见的接口调用方式,有以下几种:
- 异步调用的结果如果**存在依赖**则需要通过回调函数进行嵌套 - 异步调用的结果如果**存在依赖**则需要通过回调函数进行嵌套
### 回调地狱的举例
假设买菜做饭洗碗倒厨余垃圾都是异步的
但真实的场景中实际的操作流程是买菜成功之后才能开始做饭做饭成功后才能开始洗碗洗碗结束后 再倒厨余垃圾这里的一系列动作就涉及到了多层嵌套调用也就是回调地狱
ES5 当进行多层嵌套回调时会导致代码层次过多很难进行后续维护和二次开发而且会导致**回调地狱**的问题ES6 中的 Promise 就可以解决这两个问题 ## 为什么需要 Promise
## Promise 概述
### 为什么需要 Promise
如上一段所述Javascript 单线程语早期我们解决异步场景时部分情况都是通过回调函数来进 如上一段所述Javascript 单线程语早期我们解决异步场景时部分情况都是通过回调函数来进
### 回调的定义
把函数A传给另一个函数B调用那么函数A就是回调函数
例如在浏览器中发送 ajax 请求就是常个异步场景发送请求后需要等待一段时间等服务端响应之后我们才能拿到结果如果我们希望在异步结束之后执某个操作就只能通过**回调函数**这样的式进操作 例如在浏览器中发送 ajax 请求就是常个异步场景发送请求后需要等待一段时间等服务端响应之后我们才能拿到结果如果我们希望在异步结束之后执某个操作就只能通过**回调函数**这样的式进操作
```js ```js
@ -61,18 +58,72 @@ dynamicFunc(function () {
例如上这个例dynamicFunc 就是个异步函数 setTimeout 会在 1s 之后调 callback 函数按照上的调最终 1s 之后会打印 qian gu 这个结果 例如上这个例dynamicFunc 就是个异步函数 setTimeout 会在 1s 之后调 callback 函数按照上的调最终 1s 之后会打印 qian gu 这个结果
同样的如果后续还有内容需要在异步函数结束时输出就需要多个异步函数进嵌套常不利于后续的维护而且会导致**回调地狱**的问题
为了能使回调函数以更优雅的式进 ES6 语法中新增了个名为 Promise 的新规范
### 回调的缺点
回调的写法比较直观不需要 return层层嵌套即可但也存在两个问题
- 1如果嵌套过深则会出现**回调地狱**的问题
- 2不同的函数回调的参数在写法上可能不一致导致不规范且需要**单独记忆**
我们来具体看看这两个问题
**1回调地狱的问题**
如果后续还有内容需要在异步函数结束时输出就需要多个异步函数进嵌套常不利于后续的维护而且会导致**回调地狱**的问题
```js ```js
setTimeout(function () { setTimeout(function () {
console.log('qiangu1'); console.log('qiangu1');
setTimeout(function () { setTimeout(function () {
console.log('qiangu2'); console.log('qiangu2');
setTimeout(function () {
console.log('qiangu3');
}, 3000);
}, 2000); }, 2000);
}, 1000); }, 1000);
``` ```
为了能使回调函数以更优雅的式进 ES6 语法中新增了个名为 Promise 的新规范 关于回调地狱我们来举一个形象的例子
假设买菜做饭洗碗倒厨余垃圾都是异步的
但真实的场景中实际的操作流程是买菜成功之后才能开始做饭做饭成功后才能开始洗碗洗碗完成后 再倒厨余垃圾这里的一系列动作就涉及到了多层嵌套调用也就是回调地狱
ES5 当进行多层嵌套回调时会导致代码层次过多很难进行后续维护和二次开发而且会导致**回调地狱**的问题ES6 中的 Promise 就可以解决这两个问题
**2回调的写法不一致问题**
```js
// Node.js 读取文件时,成功回调和失败回调,是通过 error参数来区分
readFile('d:\\readme.text', function (error, data) {
if (error) {
console.log('文件读取失败');
} else {
console.log('文件读取成功');
}
})
// jQuery的 ajax 写法中,成功回调和失败回调,是通过两个回调函数来区分
$.ajax({
url: '/ajax.json',
success: function (response) {
console.log('文件读取成功');
},
error: function (err) {
console.log('文件读取失败');
}
})
```
我们可以看到上面的代码中成功回调和失败回调写法不统一需要单独记忆容易出错
### Promise 的介绍和优点 ### Promise 的介绍和优点
@ -84,6 +135,24 @@ Promise 对象, 可以**用同步的表现形式来书写异步代码**(也就
- 语法非常简洁可读性强便于后期维护Promise 对象提供了简洁的 API使得控制异步操作更加容易 - 语法非常简洁可读性强便于后期维护Promise 对象提供了简洁的 API使得控制异步操作更加容易
Promise 的伪代码结构大概是这样的
```js
// 伪代码1
myPromise()
.then(function () { }, function () { })
.then(function () { }, function () { })
.then(function () { }, function () { })
// 伪代码2
是时候展现真正的厨艺了()
.然后(买菜)
.然后(做饭)
.然后(洗碗)
```
上面的伪代码可以看出即便在业务逻辑上是层层嵌套但是代码写法上却十分优雅也没有过多的嵌套
## Promise 基础 ## Promise 基础
### Promise 的基本用法 ### Promise 的基本用法
@ -132,7 +201,7 @@ promiseA()
上方代码中当从接口返回的数据`data.retCode`的值接口返回码不同时可能会走 resolve也可能会走 reject这个由你自己的业务决定 上方代码中当从接口返回的数据`data.retCode`的值接口返回码不同时可能会走 resolve也可能会走 reject这个由你自己的业务决定
上面的写法中是将 promise 实例定义成了一个**函数** `PromiseA`我们也可以将 promise 实例定义成一个**变量** `promiseB`达到的效果是一模一样的写法如下写法上略有区别 上面的写法中是将 promise 实例定义成了一个**函数** `promiseA`我们也可以将 promise 实例定义成一个**变量** `promiseB`达到的效果是一模一样的写法如下写法上略有区别
```js ```js
// 第一步model层的接口封装 // 第一步model层的接口封装