From 61d56437eb207afdae7381a7aacfe712193e0743 Mon Sep 17 00:00:00 2001 From: qianguyihao Date: Thu, 27 May 2021 21:56:03 +0800 Subject: [PATCH] =?UTF-8?q?add:=20=E5=AE=8F=E4=BB=BB=E5=8A=A1=E5=92=8C?= =?UTF-8?q?=E5=BE=AE=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../01-ES6的介绍和环境配置.md | 0 .../02-ES5中的严格模式.md | 0 .../03-ES5中的一些扩展.md | 0 .../04-ES6:变量 let、const 和块级作用域.md | 0 .../05-ES6:变量的解构赋值.md | 0 .../06-ES6:箭头函数.md | 0 .../07-剩余参数和扩展运算符.md | 0 .../08-字符串、数组、对象的扩展.md | 0 .../09-内置对象扩展:Set数据结构.md | 0 .../ES6:Symbol.md | 0 .../00-服务器分类及PHP入门.md | 0 .../01-单线程和异步.md | 2 +- .../02-Ajax入门和发送http请求.md | 9 +- .../03-Ajax传输json和XML.md | 0 .../04-同源和跨域.md | 0 .../05-Promise入门详解.md | 104 ++++++++++++++---- .../06-Promise的链式调用.md | 0 .../07-Promise的静态方法.md | 0 .../08-Async Await函数详解.md | 0 .../09-宏任务和微任务.md | 65 +++++++++++ .../函数封装-Ajax发送http请求(get&post).md | 0 .../模板引擎.md | 0 07-JavaScript进阶/Promise的一些题目.md | 28 +++++ 23 files changed, 185 insertions(+), 23 deletions(-) rename {06-JavaScript基础:ES6语法 => 05-JavaScript基础:ES6语法}/01-ES6的介绍和环境配置.md (100%) rename {06-JavaScript基础:ES6语法 => 05-JavaScript基础:ES6语法}/02-ES5中的严格模式.md (100%) rename {06-JavaScript基础:ES6语法 => 05-JavaScript基础:ES6语法}/03-ES5中的一些扩展.md (100%) rename {06-JavaScript基础:ES6语法 => 05-JavaScript基础:ES6语法}/04-ES6:变量 let、const 和块级作用域.md (100%) rename {06-JavaScript基础:ES6语法 => 05-JavaScript基础:ES6语法}/05-ES6:变量的解构赋值.md (100%) rename {06-JavaScript基础:ES6语法 => 05-JavaScript基础:ES6语法}/06-ES6:箭头函数.md (100%) rename {06-JavaScript基础:ES6语法 => 05-JavaScript基础:ES6语法}/07-剩余参数和扩展运算符.md (100%) rename {06-JavaScript基础:ES6语法 => 05-JavaScript基础:ES6语法}/08-字符串、数组、对象的扩展.md (100%) rename {06-JavaScript基础:ES6语法 => 05-JavaScript基础:ES6语法}/09-内置对象扩展:Set数据结构.md (100%) rename {06-JavaScript基础:ES6语法 => 05-JavaScript基础:ES6语法}/ES6:Symbol.md (100%) rename {05-JavaScript基础:异步编程和Ajax => 06-JavaScript异步编程:Ajax和Promise}/00-服务器分类及PHP入门.md (100%) rename {05-JavaScript基础:异步编程和Ajax => 06-JavaScript异步编程:Ajax和Promise}/01-单线程和异步.md (97%) rename {05-JavaScript基础:异步编程和Ajax => 06-JavaScript异步编程:Ajax和Promise}/02-Ajax入门和发送http请求.md (96%) rename {05-JavaScript基础:异步编程和Ajax => 06-JavaScript异步编程:Ajax和Promise}/03-Ajax传输json和XML.md (100%) rename {05-JavaScript基础:异步编程和Ajax => 06-JavaScript异步编程:Ajax和Promise}/04-同源和跨域.md (100%) rename 06-JavaScript基础:ES6语法/10-Promise入门详解.md => 06-JavaScript异步编程:Ajax和Promise/05-Promise入门详解.md (82%) rename 06-JavaScript基础:ES6语法/11-Promise的链式调用.md => 06-JavaScript异步编程:Ajax和Promise/06-Promise的链式调用.md (100%) rename 06-JavaScript基础:ES6语法/12-Promise的静态方法.md => 06-JavaScript异步编程:Ajax和Promise/07-Promise的静态方法.md (100%) rename 06-JavaScript基础:ES6语法/13-ES7:Async Await函数详解.md => 06-JavaScript异步编程:Ajax和Promise/08-Async Await函数详解.md (100%) create mode 100644 06-JavaScript异步编程:Ajax和Promise/09-宏任务和微任务.md rename 05-JavaScript基础:异步编程和Ajax/04-函数封装-Ajax发送http请求(get&post).md => 06-JavaScript异步编程:Ajax和Promise/函数封装-Ajax发送http请求(get&post).md (100%) rename 05-JavaScript基础:异步编程和Ajax/05-模板引擎.md => 06-JavaScript异步编程:Ajax和Promise/模板引擎.md (100%) diff --git a/06-JavaScript基础:ES6语法/01-ES6的介绍和环境配置.md b/05-JavaScript基础:ES6语法/01-ES6的介绍和环境配置.md similarity index 100% rename from 06-JavaScript基础:ES6语法/01-ES6的介绍和环境配置.md rename to 05-JavaScript基础:ES6语法/01-ES6的介绍和环境配置.md diff --git a/06-JavaScript基础:ES6语法/02-ES5中的严格模式.md b/05-JavaScript基础:ES6语法/02-ES5中的严格模式.md similarity index 100% rename from 06-JavaScript基础:ES6语法/02-ES5中的严格模式.md rename to 05-JavaScript基础:ES6语法/02-ES5中的严格模式.md diff --git a/06-JavaScript基础:ES6语法/03-ES5中的一些扩展.md b/05-JavaScript基础:ES6语法/03-ES5中的一些扩展.md similarity index 100% rename from 06-JavaScript基础:ES6语法/03-ES5中的一些扩展.md rename to 05-JavaScript基础:ES6语法/03-ES5中的一些扩展.md diff --git a/06-JavaScript基础:ES6语法/04-ES6:变量 let、const 和块级作用域.md b/05-JavaScript基础:ES6语法/04-ES6:变量 let、const 和块级作用域.md similarity index 100% rename from 06-JavaScript基础:ES6语法/04-ES6:变量 let、const 和块级作用域.md rename to 05-JavaScript基础:ES6语法/04-ES6:变量 let、const 和块级作用域.md diff --git a/06-JavaScript基础:ES6语法/05-ES6:变量的解构赋值.md b/05-JavaScript基础:ES6语法/05-ES6:变量的解构赋值.md similarity index 100% rename from 06-JavaScript基础:ES6语法/05-ES6:变量的解构赋值.md rename to 05-JavaScript基础:ES6语法/05-ES6:变量的解构赋值.md diff --git a/06-JavaScript基础:ES6语法/06-ES6:箭头函数.md b/05-JavaScript基础:ES6语法/06-ES6:箭头函数.md similarity index 100% rename from 06-JavaScript基础:ES6语法/06-ES6:箭头函数.md rename to 05-JavaScript基础:ES6语法/06-ES6:箭头函数.md diff --git a/06-JavaScript基础:ES6语法/07-剩余参数和扩展运算符.md b/05-JavaScript基础:ES6语法/07-剩余参数和扩展运算符.md similarity index 100% rename from 06-JavaScript基础:ES6语法/07-剩余参数和扩展运算符.md rename to 05-JavaScript基础:ES6语法/07-剩余参数和扩展运算符.md diff --git a/06-JavaScript基础:ES6语法/08-字符串、数组、对象的扩展.md b/05-JavaScript基础:ES6语法/08-字符串、数组、对象的扩展.md similarity index 100% rename from 06-JavaScript基础:ES6语法/08-字符串、数组、对象的扩展.md rename to 05-JavaScript基础:ES6语法/08-字符串、数组、对象的扩展.md diff --git a/06-JavaScript基础:ES6语法/09-内置对象扩展:Set数据结构.md b/05-JavaScript基础:ES6语法/09-内置对象扩展:Set数据结构.md similarity index 100% rename from 06-JavaScript基础:ES6语法/09-内置对象扩展:Set数据结构.md rename to 05-JavaScript基础:ES6语法/09-内置对象扩展:Set数据结构.md diff --git a/06-JavaScript基础:ES6语法/ES6:Symbol.md b/05-JavaScript基础:ES6语法/ES6:Symbol.md similarity index 100% rename from 06-JavaScript基础:ES6语法/ES6:Symbol.md rename to 05-JavaScript基础:ES6语法/ES6:Symbol.md diff --git a/05-JavaScript基础:异步编程和Ajax/00-服务器分类及PHP入门.md b/06-JavaScript异步编程:Ajax和Promise/00-服务器分类及PHP入门.md similarity index 100% rename from 05-JavaScript基础:异步编程和Ajax/00-服务器分类及PHP入门.md rename to 06-JavaScript异步编程:Ajax和Promise/00-服务器分类及PHP入门.md diff --git a/05-JavaScript基础:异步编程和Ajax/01-单线程和异步.md b/06-JavaScript异步编程:Ajax和Promise/01-单线程和异步.md similarity index 97% rename from 05-JavaScript基础:异步编程和Ajax/01-单线程和异步.md rename to 06-JavaScript异步编程:Ajax和Promise/01-单线程和异步.md index 2d27e06..3282d90 100644 --- a/05-JavaScript基础:异步编程和Ajax/01-单线程和异步.md +++ b/06-JavaScript异步编程:Ajax和Promise/01-单线程和异步.md @@ -169,7 +169,7 @@ setTimeout(() => { 上面的代码中,等到 1 秒之后,真的会执行异步任务吗?其实不是。 -在浏览器中, setTimeout()/ setInterval() 的每调用一次定时器的最小时间间隔是**4ms**,这通常是由于函数嵌套导致(嵌套层级达到一定深度),或者是由于已经执行的 setInterval 的回调函数阻塞导致的。 +在浏览器中, setTimeout()/ setInterval() 的每调用一次定时器的最小时间间隔是**4毫秒**,这通常是由于函数嵌套导致(嵌套层级达到一定深度),或者是由于已经执行的 setInterval 的回调函数阻塞导致的。 上面的案例中,异步任务需要等待 1004 毫秒之后,才会从 Event Table 进入到 Event Queue。这在面试中也经常被问到。 diff --git a/05-JavaScript基础:异步编程和Ajax/02-Ajax入门和发送http请求.md b/06-JavaScript异步编程:Ajax和Promise/02-Ajax入门和发送http请求.md similarity index 96% rename from 05-JavaScript基础:异步编程和Ajax/02-Ajax入门和发送http请求.md rename to 06-JavaScript异步编程:Ajax和Promise/02-Ajax入门和发送http请求.md index 4f44c29..c575909 100644 --- a/05-JavaScript基础:异步编程和Ajax/02-Ajax入门和发送http请求.md +++ b/06-JavaScript异步编程:Ajax和Promise/02-Ajax入门和发送http请求.md @@ -192,8 +192,8 @@ xmlhttp.onreadystatechange = function () { 封装 Ajax 请求的代码如下:(get 请求为例) ```js -// 封装 Ajax为公共函数 -function myAjax(url, callback) { +// 封装 Ajax为公共函数:传入回调函数 success 和 fail +function myAjax(url, success, fail) { // 1、创建XMLHttpRequest对象 var xmlhttp; if (window.XMLHttpRequest) { @@ -210,7 +210,10 @@ function myAjax(url, callback) { if (xmlhttp.readyState === 4 && xmlhttp.status === 200) { var obj = JSON.parse(xmlhttp.responseText); console.log('数据返回成功:' + Jobj); - callback(obj); + success && success(xmlhttp.responseText); + } else { + // 这里的 && 符号,意思是:如果传了 fail 参数,就调用后面的 fail();如果没传 fail 参数,就不调用后面的内容。因为 fail 参数不一定会传。 + fail && fail(new Error('接口请求失败')); } }; } diff --git a/05-JavaScript基础:异步编程和Ajax/03-Ajax传输json和XML.md b/06-JavaScript异步编程:Ajax和Promise/03-Ajax传输json和XML.md similarity index 100% rename from 05-JavaScript基础:异步编程和Ajax/03-Ajax传输json和XML.md rename to 06-JavaScript异步编程:Ajax和Promise/03-Ajax传输json和XML.md diff --git a/05-JavaScript基础:异步编程和Ajax/04-同源和跨域.md b/06-JavaScript异步编程:Ajax和Promise/04-同源和跨域.md similarity index 100% rename from 05-JavaScript基础:异步编程和Ajax/04-同源和跨域.md rename to 06-JavaScript异步编程:Ajax和Promise/04-同源和跨域.md diff --git a/06-JavaScript基础:ES6语法/10-Promise入门详解.md b/06-JavaScript异步编程:Ajax和Promise/05-Promise入门详解.md similarity index 82% rename from 06-JavaScript基础:ES6语法/10-Promise入门详解.md rename to 06-JavaScript异步编程:Ajax和Promise/05-Promise入门详解.md index a3de1e0..929dda7 100644 --- a/06-JavaScript基础:ES6语法/10-Promise入门详解.md +++ b/06-JavaScript异步编程:Ajax和Promise/05-Promise入门详解.md @@ -143,17 +143,17 @@ myPromise() 上面的伪代码可以看出,即便在业务逻辑上是层层嵌套,但是代码写法上,却十分优雅,也没有过多的嵌套。 -## Promise 基础 +## Promise 对象的用法和状态 -### Promise 的基本用法 +### 使用 Promise 的基本步骤 (1)通过 `new Promise()` 构造出一个 Promise 实例。Promise 的构造函数中传入一个参数,这个参数是一个函数,该函数用于处理异步任务。 (2)函数中传入两个参数:resolve 和 reject,分别表示异步执行成功后的回调函数和异步执行失败后的回调函数。代表着我们需要改变当前实例的状态到**已完成**或是**已拒绝**。 -(3)通过 promise.then() 处理返回结果(这里的 `promise` 指的是 Promise 实例)。 +(3)通过 promise.then() 和 promise.catch() 处理返回结果(这里的 `promise` 指的是 Promise 实例)。 -Promise 的精髓在于**对异步操作的状态管理**。 +看到这里,你估计还是不知道 Promise 怎么使用。我们不妨来看一下 Promise 有哪些状态,便一目了然。要知道,Promise 的精髓在于**对异步操作的状态管理**。 ### promise 对象的 3 个状态 @@ -163,13 +163,17 @@ Promise 的精髓在于**对异步操作的状态管理**。 - 失败:rejected -(1)当 new Promise()执行之后,promise 对象的状态会被初始化为`pending`,这个状态是初始化状态。`new Promise()`这行代码,括号里的内容是同步执行的。括号里定义一个 function,function 有两个参数:resolve 和 reject。如下: +**步骤 1**: + +当 new Promise()执行之后,promise 对象的状态会被初始化为`pending`,这个状态是初始化状态。`new Promise()`这行代码,括号里的内容是同步执行的。括号里可以再定义一个 异步任务的 function,function 有两个参数:resolve 和 reject。如下: - 如果请求成功了,则执行 resolve(),此时,promise 的状态会被自动修改为 fulfilled。 - 如果请求失败了,则执行 reject(),此时,promise 的状态会被自动修改为 rejected -(2)promise.then()方法,括号里面有两个参数,分别代表两个函数 function1 和 function2: +(2)promise.then()方法:**只有 promise 的状态被改变之后,才会走到 then 或者 catch**。也就是说,在 new Promise()的时候,如果没有写 resolve(),则 promise.then() 不执行;如果没有写 reject(),则 promise.catch() 不执行。 + +`then()`括号里面有两个参数,分别代表两个函数 function1 和 function2: - 如果 promise 的状态为 fulfilled(意思是:如果请求成功),则执行 function1 里的内容 @@ -177,43 +181,103 @@ Promise 的精髓在于**对异步操作的状态管理**。 另外,resolve()和 reject()这两个方法,是可以给 promise.then()传递参数的。 -关于 promise 的状态改变,伪代码及注释如下: +关于 promise 的状态改变,以及如何处理状态改变,伪代码及注释如下: ```javascript // 创建 promise 实例 let promise = new Promise((resolve, reject) => { //进来之后,状态为pending - console.log('111'); //这行代码是同步的 + console.log('同步代码'); //这行代码是同步的 //开始执行异步操作(这里开始,写异步的代码,比如ajax请求 or 开启定时器) if (异步的ajax请求成功) { console.log('333'); - resolve('haha'); //如果请求成功了,请写resolve(),此时,promise的状态会被自动修改为fulfilled + resolve('请求成功,并传参'); //如果请求成功了,请写resolve(),此时,promise的状态会被自动修改为fulfilled(成功状态) } else { - reject('555'); //如果请求失败了,请写reject(),此时,promise的状态会被自动修改为rejected + reject('请求失败,并传参'); //如果请求失败了,请写reject(),此时,promise的状态会被自动修改为rejected(失败状态) } }); console.log('222'); -//调用promise的then() +//调用promise的then():开始处理成功和失败 promise.then( (successMsg) => { - //如果promise的状态为fulfilled,则执行这里的代码 - console.log(successMsg, '成功了'); + // 处理 promise 的成功状态:如果promise的状态为fulfilled,则执行这里的代码 + console.log(successMsg, '成功了'); // 这里的 successMsg 是前面的 resolve('请求成功,并传参') 传过来的参数 }, (errorMsg) => { - //如果promise的状态为rejected,则执行这里的代码 - console.log(errorMsg, '失败了'); + //处理 promise 的失败状态:如果promise的状态为rejected,则执行这里的代码 + console.log(errorMsg, '失败了'); // 这里的 errorMsg 是前面的 reject('请求失败,并传参') 传过来的参数 } ); ``` -**几点补充**: +上面的注释要多看几遍。 -(1)Promise 的状态一旦改变,就不能再变。 +## 几点补充 -(2)Promise 的状态改变,是不可逆的。 +### new Promise() 是同步代码 -为了解释这两点,我们来看个例子: +`new Promise()`这行代码本身是同步的。promise 如果没有使用 resolve 或 reject 更改状态时,状态为 pending。 + +**举例1**: + +```js +const promiseA = new Promise((resolve, reject) => {}); +console.log(promiseA); // 此时 promise 的状态为 pending(准备阶段) +``` + +上面的代码中,我既没有写 reslove(),也没有写 reject()。也就是说,这个 promise 一直处于准备阶段。 + +当完成异步任务之后,状态分为成功或失败,此时我们就可以用 reslove() 和 reject() 来修改 promise 的状态。 + +**举例2**: + +```js +new Promise((resolve, reject) => { + console.log('promise1'); // 这行代码是同步代码,会立即执行 +}).then((res) => { + console.log('promise then:' + res); // 这行代码不会执行,因为前面没有写 resolve(),所以走不到 .then +}); +``` + +打印结果: + +``` +promise1 +``` + + +上方代码,仔细看注释:如果前面没有写 `resolve()`,那么后面的 `.then`是不会执行的。 + +**举例3**: + +```js +new Promise((resolve, reject) => { + resolove(); + console.log('promise1'); // 代码1:同步任务,会立即执行 +}).then(res => { + console.log('promise then)'; // 代码2:异步任务中的微任务 +}) + +console.log('千古壹号'); // 代码3:同步任务 +``` + +打印结果: + +``` +promise1 +千古壹号 +promise then +``` + +代码解释:代码1是同步代码,所以最先执行。代码2是**微任务**里面的代码,所以要先等同步任务(代码3)先执行完。当写完`resolve();`之后,就会立刻把 `.then()`里面的代码加入到微任务队列当中。 + +补充知识:异步任务分为“宏任务”、“微任务”两种。我们到后续的章节中再详细讲。 + + +### Promise 的状态一旦改变,就不能再变 + +代码举例: ```js const p = new Promise((resolve, reject) => { @@ -229,6 +293,8 @@ p.then((res) => { 上方代码的打印结果是 1,而不是 2,详见注释。 +### Promise 的状态改变,是不可逆的 + ### 小结 1、promise 有三种状态:等待中、成功、失败。等待中状态可以更改为成功或失败,已经更改过状态后⽆法继续更改(例如从失败改为成功)。 diff --git a/06-JavaScript基础:ES6语法/11-Promise的链式调用.md b/06-JavaScript异步编程:Ajax和Promise/06-Promise的链式调用.md similarity index 100% rename from 06-JavaScript基础:ES6语法/11-Promise的链式调用.md rename to 06-JavaScript异步编程:Ajax和Promise/06-Promise的链式调用.md diff --git a/06-JavaScript基础:ES6语法/12-Promise的静态方法.md b/06-JavaScript异步编程:Ajax和Promise/07-Promise的静态方法.md similarity index 100% rename from 06-JavaScript基础:ES6语法/12-Promise的静态方法.md rename to 06-JavaScript异步编程:Ajax和Promise/07-Promise的静态方法.md diff --git a/06-JavaScript基础:ES6语法/13-ES7:Async Await函数详解.md b/06-JavaScript异步编程:Ajax和Promise/08-Async Await函数详解.md similarity index 100% rename from 06-JavaScript基础:ES6语法/13-ES7:Async Await函数详解.md rename to 06-JavaScript异步编程:Ajax和Promise/08-Async Await函数详解.md diff --git a/06-JavaScript异步编程:Ajax和Promise/09-宏任务和微任务.md b/06-JavaScript异步编程:Ajax和Promise/09-宏任务和微任务.md new file mode 100644 index 0000000..108f6a1 --- /dev/null +++ b/06-JavaScript异步编程:Ajax和Promise/09-宏任务和微任务.md @@ -0,0 +1,65 @@ +## 准备知识 + +- 在执行一个 Promise 对象的时候,当走完`resolve();`之后,就会立刻把 `.then()`里面的代码加入到**微任务队列**当中。 + +- 任务的一般执行顺序:**同步任务 --> 微任务 --> 宏任务**。 + +## 代码举例 + +### 举例 1:宏任务和微任务的执行顺序 + +```js +setTimeout(() => { + // 宏任务 + console.log('setTimeout'); +}, 0); + +new Promise((resolve, reject) => { + resolve(); + console.log('promise1'); // 同步任务 +}).then((res) => { + // 微任务 + console.log('promise then'); +}); + +console.log('qianguyihao'); // 同步任务 +``` + +打印结果: + +``` +promise1 +qianguyihao +promise then +setTimeout +``` + +上方代码执行的顺序依次是:**同步任务 --> 微任务 --> 宏任务**。 + +### 举例 2:宏任务和微任务的嵌套 + +```js +new Promise((resolve, reject) => { + setTimeout(() => { + resolve(); + console.log('setTimeout'); + }, 0); + console.log('promise1'); +}).then((res) => { + // 微任务 + console.log('promise then'); +}); + +console.log('qianguyihao'); +``` + +打印结果: + +``` +promise1 +qianguyihao +setTimeout +promise then +``` + +上方代码解释:在执行宏任务的**过程中**,创建了一个微任务。但是需要**先把当前这个宏任务执行完**,再去轮询异步任务的队列,进而执行微任务。 diff --git a/05-JavaScript基础:异步编程和Ajax/04-函数封装-Ajax发送http请求(get&post).md b/06-JavaScript异步编程:Ajax和Promise/函数封装-Ajax发送http请求(get&post).md similarity index 100% rename from 05-JavaScript基础:异步编程和Ajax/04-函数封装-Ajax发送http请求(get&post).md rename to 06-JavaScript异步编程:Ajax和Promise/函数封装-Ajax发送http请求(get&post).md diff --git a/05-JavaScript基础:异步编程和Ajax/05-模板引擎.md b/06-JavaScript异步编程:Ajax和Promise/模板引擎.md similarity index 100% rename from 05-JavaScript基础:异步编程和Ajax/05-模板引擎.md rename to 06-JavaScript异步编程:Ajax和Promise/模板引擎.md diff --git a/07-JavaScript进阶/Promise的一些题目.md b/07-JavaScript进阶/Promise的一些题目.md index 8a32162..d62b097 100644 --- a/07-JavaScript进阶/Promise的一些题目.md +++ b/07-JavaScript进阶/Promise的一些题目.md @@ -94,3 +94,31 @@ a成功 b成功 b接口返回的内容 ``` + +### 题目 3 + +举例1: + +```js +new Promise((resolve, reject) => { + resolove(); + console.log('promise1'); // 代码1 +}).then(res => { + console.log('promise then)'; // 代码2:微任务 +}) + +console.log('千古壹号'); // 代码3 +``` + +打印结果: + +``` +promise1 +千古壹号 +promise then +``` + +代码解释:代码1是同步代码,所以最先执行。代码2是**微任务**里面的代码,所以要先等同步任务(代码3)先执行完。 + +当写完`resolove();`之后,就会立刻把 `.then()`里面的代码加入到微任务队列当中。 +