JS深挖:异步方案发展史 ——回调函数、Promise和async/await

白衣黑月 -
JS深挖:异步方案发展史 ——回调函数、Promise和async/await
本章围绕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);
    });
  });
});
特别申明:本文内容来源网络,版权归原作者所有,如有侵权请立即与我们联系(cy198701067573@163.com),我们将及时处理。
下一篇: Express

Tags 标签

javascript前端es6node.js

扩展阅读

加个好友,技术交流

1628738909466805.jpg