From b34943e616982abe979e6d72a7c77fc4744086f1 Mon Sep 17 00:00:00 2001 From: qianguyihao Date: Mon, 17 May 2021 17:59:58 +0800 Subject: [PATCH] update: promise --- .../10-Promise入门详解.md | 87 +++++++++++-------- 08-Ajax/02-Ajax入门和发送http请求.md | 25 +++--- 2 files changed, 68 insertions(+), 44 deletions(-) diff --git a/05-JavaScript基础:ES6语法/10-Promise入门详解.md b/05-JavaScript基础:ES6语法/10-Promise入门详解.md index 510a1f1..80692d1 100644 --- a/05-JavaScript基础:ES6语法/10-Promise入门详解.md +++ b/05-JavaScript基础:ES6语法/10-Promise入门详解.md @@ -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 并不能捕获到错误。对于微任务而言(比如 promise)promise 的构造函数的异常只能被自带的 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+ 规范: +- Promises/A+ 规范: ## promise 对象的 3 个状态 @@ -483,8 +503,7 @@ request1() ## 总结 - -了解这些内容之后, 你已经对 Promise 有了基本了解。下一篇文章,我们来讲一讲 Promise在实战开发的常见用法。 +了解这些内容之后, 你已经对 Promise 有了基本了解。下一篇文章,我们来讲一讲 Promise 在实战开发的常见用法。 ## 参考链接 diff --git a/08-Ajax/02-Ajax入门和发送http请求.md b/08-Ajax/02-Ajax入门和发送http请求.md index 0a5487c..6868be1 100644 --- a/08-Ajax/02-Ajax入门和发送http请求.md +++ b/08-Ajax/02-Ajax入门和发送http请求.md @@ -2,7 +2,7 @@ ## 同步和异步 -### 同步和异步的概念 +### 同步和异步的简单理解 - 同步:必须等待前面的任务完成,才能继续后面的任务。 @@ -19,12 +19,15 @@ 我们在访问一个普通的网站时,当浏览器加载完`HTML、CSS、JS`以后,网站的内容就固定了。如果想让网站内容发生更改,就必须**刷新**页面才能够看到更新的内容。 -可如果用到**异步更新**,情况就大为改观了。比如,我们在访问新浪微博时,看到一大半了,点击底部的**加载更多**,会自动帮我们加载更多的微博,同时页面并没有刷新。 +可如果用到**异步更新**,情况就大为改观了。比如,我们在访问新浪微博时,看到一大半了,点击底部的**加载更多**,会自动帮我们加载更多的微博,同时页面并不会整体刷新。 -试想一下,如果没有异步刷新的话,每次点击“加载更多”,网页都要刷新,体验就太不好了。 +试想一下,如果没有异步刷新的话,每次点击“加载更多”,网页都要重新刷新,体验就太糟糕了。 web前端里的异步更新,就要用到 Ajax。 +关于同步和异步的更详细介绍,可以参考本项目的另外一篇文章:《JavaScript基础:ES6语法/单线程和异步》 + + ## Ajax @@ -49,9 +52,9 @@ Ajax:Asynchronous Javascript And XML(异步 JavaScript 和 XML)。它并 发送 Ajax 请求的五个步骤: -(1)创建异步对象。即 XMLHttpRequest 对象。 +(1)创建异步对象,即 XMLHttpRequest 对象。 -(2)使用open方法设置请求的参数。open(method, url, async)。参数解释:请求的方法、请求的url、是否异步。 +(2)使用open方法设置请求的参数。`open(method, url, async)`。参数解释:请求的方法、请求的url、是否异步。 (3)发送请求。 @@ -59,7 +62,7 @@ Ajax:Asynchronous Javascript And XML(异步 JavaScript 和 XML)。它并 如果要在数据完整请求回来的时候才调用,我们需要手动写一些判断的逻辑。 -(5)获取返回的数据。 +(5)服务端响应,获取返回的数据。 ### Ajax 请求:get 请求举例 @@ -644,11 +647,13 @@ echo $text; -## 我的公众号 +## 创作不易,赞赏作者 -想学习**代码之外的技能**?不妨关注我的微信公众号:**千古壹号**(id:`qianguyihao`)。 +如果你觉得本教程对你有帮助,或者你想催更,不妨赞赏一下。 -扫一扫,你将发现另一个全新的世界,而这将是一场美丽的意外: +你的赞赏和认可,是我最大的动力: + + +![](http://img.smyhvae.com/20210510_2100.jpg) -![](http://img.smyhvae.com/2016040102.jpg)