本章围绕JS中异步进行展开,解决问题: 1、什么是异步,为何出现? 2、什么是回调函数、回调地狱? 3、Promise的介绍和理解? 4、async/await的理解和使用?
1、JS中什么是异步?为何出现?
答:
背景:JS执行代码是一行行的执行,只有上一行有了结果后才继续下一行;但,有的代码在短期内并不会返回结果,这时我们不应该傻傻等待,而应该立即继续执行后面的代码,等到代码返回结果了再去处理它。等待返回结果就是同步,不等结果就是异步
异步出现就是为了更高效率的执行代码,而不是机械怼的等待执行;
2、什么是回调函数,回调地狱?
答:
回调函数:回调函数是作为参数传给另一个函数的函数,然后通过在外部函数内部调用该回调函数以完成某种操作。 为何需要回调:其本质是异步编程的一种解决方案,主要是用来作为异步函数执行完成的标志; 回调地狱:多个回调函数相互嵌套,导致代码缩进过多,且结构混乱难以更新维护,这种代码结构就是回调地狱; 如代码1所示;
3、Promise的理解,主要有几个方面
1)Promise是什么?
2)Promise实现详解;
3)Promise是如何解决异步问题的?
4)Promise输出结果题技巧汇总;
答:
1)定义:Promise本身是一个构造函数,通过调用内部的方法解决异步问题和回调地狱; 2)具体实现: - 它本身有三个状态:pending、resolved、rejected; - 任务交给Promise时是pending状态,只能由pending-> fulfilled或 pending-> reject,且不再改变; - Promise本身是同步的立即执行函数,只有当其执行到 resolve/reject , 此时是异步操作,会立即异步执行 then / catch 对应的内容,然后回来执行同步代码; 3)如何解决: - 关键:Promise本身相关操作都是同步的,只是能用来获取异步结束的结果并即使处理 - 通过创建Promise对象,异步操作放对象里; - resolve()和 reject()本身都是同步的操作,只是放在异步函数中,用来捕获异步结束并改变当前状态; - .then是实现异步的核心,它会在Promise状态改变的同时,获取返回的结果,若当前状态未改变,就push进数组,当resolve 或 reject 执行的时候,将数组中的函数执行; 4)输出结果技巧汇总: - 链式调用,注意.then()一定会返回一个Promise对象: 上一个then()若返回Promise对象,则用这个对象的状态和value; 上一个then()若返回数值,则返回Promise<fulfilled>,value为数值; 上一个then()若无返回值,则返回Promise<fulfilled>,value为undefined; - 链式调用判断输出时,转化成单层调用的方式进行判断,但仅供判断(具体看参考); 第一种,上级then没有返回值,转化成一级的形式进行判断; 第二种,上级then有return值,下级then必须在上级结束后,才能继续;
4、async/await
1)是什么?为何引入? 2)如何使用? 3)比Promise的优势? 4)代码输出题技巧?
答:
1)是什么,引入原因: async 函数是 Generator 函数的语法糖,使用 关键字 async 来表示,在函数内部使用 await 来表示异步 引入async/await解决异步是因为Promise存在以下问题: - Promise的链式调用结构还是有些复杂; - Promise的中间值传递麻烦; - Promise的错误捕获非常冗余; 2)怎么用: - 用同步的方式执行异步的操作; - 在async函数中,await规定了异步操作只能依次执行; - async函数后面跟Promise对象才能实现效果; - async函数本身返回的是Promise对象,对象值与返回值有关; 3)比Promise的优势: - 代码更加同步,Promise的.then链式调用还是有些复杂; - 解决了Promise的中间值传递麻烦; - 有成熟的 try/catch,不像Promise的错误捕获非常冗余; 4)代码输出: 【✨】 - 若await执行async内部的函数,如async fn(),会阻塞原执行环境,接着分为两种情况 - 若fn是同步执行,立即返回,那么阻塞的环境作为一个微任务加入微任务队列; - 若fn是异步任务,则加入对应队列,而阻塞环境等fn执行完后,加入微任务队列;
// 代码1(回调地狱)
http.get('https://api.github.com/users', function(users) {
/* Display all users */
console.log(users);
http.get('https://api.github.com/repos/javascript/contributors?q=contributions&order=desc', function(contributors) {
/* Display all top contributors */
console.log(contributors);
http.get('https://api.github.com/users/Jhon', function(userData) {
/* Display user with username 'Jhon' */
console.log(userData);
});
});
});
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。