es6之异步编程(学习小结)

最近开始学习es6的新语法特性,我参看的教程是阮一峰老师的教程,这个教程真的写得非常好,有兴趣进行全面学习的伙伴可以参看此教程。教程链接:ES6入门教程
相比es5的语法特性,es6最为突出的两大特性非module,class和异步编程莫属。
module,class这部分的改动更贴近于类似Java,C#等后端语言的语法特性。
废话不多说,首先在进入正题异步编程之前得先明确一件事情:异步编程与多线程编程之间的区别与联系? 相信这个问题也是很多伙伴心中的困惑(这个困惑我也有),这里有一篇大佬写的对于此问题的详细解释的博客,有一语道破天机的奇效:异步编程与多线程编程之间的区别与联系
下面,我简单的阐述一下就js而言,我对此问题的看法。
首先,多线程以及异步编程都是为了处理线程阻塞的问题,只不过这是两种完全不同的方式。例如Java,它可以同时开启多个线程分工进行运作,极大的提高效率。而js是单线程的执行环境,无法开启多线程,但是为了解决线程阻塞的情形,所以就产出了异步编程的处理方式。
最传统的异步编程方式是利用回调函数和事件的方式实现,最常见的场景有settimeout函数,然后es6里面出现了Promise对象来处理异步请求。
Promise对象里面有三个最常用的函数,分别是resolve,reject和then。其最简单的执行流程就是给一个异步操作定义一个promise对象,然后在resolve函数里定义成功异步时所要调用的函数,在reject函数里面定义异步请求失败所需要执行的函数,最后通过then方法来调用异步操作。
promise里面还有很多具体的细节,大家可以参考教程。
其实Promise在处理异步的方式上相比于传统的回调函数的方式最大的便利在于,将传统的多层回调函数嵌套而造成的横向"回调函数地狱"变成纵向的链式结构,即使用then函数。但是此操作也只是对回调函数进行了优化,代码还是显得有些冗余,所以此时新函数Generator 和新关键字yield出现了。
这两组合天生就适合处理这种多状态的事情。Generator 函数可以暂停函数的执行,返回任意表达式的值。简单来说,将异步操作写在yield表达式里面,等到调用next方法时再往后执行。
最后,主角async,await登场了,其实Generator 以及挺好用了,为何还要这两?这两说白了就是Generator 的语法糖,使得异步操作变得更加方便,可以类比箭头函数的感觉。
async,await的具体语法我在此也不多叙述,大家可以参看教程。
说了这么一大串,肯定有人想知道,一个异步编程是不是可以用这三种方式实现?答案是肯定的,在教程async函数这节里,就有一个案例是使用这三种方法来实现一个异步功能。
最后,我这里做了一个用异步编程的方式来包装浏览器原生的ajax的demo:
html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="Access-Control-Allow-Origin" content="https://www.baidu.com/" />
    <title>Document</title>
    <script type="module" src="./main.js"></script>
</head>
<body>
    <button id="ajaxButton" type="button">Make a request</button>
</body>
</html>

main.js:

import Ajax from './ajax.js';

class Main {
  static start() {
    document.getElementById('ajaxButton').addEventListener('click', Main.clickHandler);
  }

  static async clickHandler() {
    const url = './package.json';
    const HTTPMethodType = 'GET';
    const headerMap = new Map();
    headerMap.set('Accept', 'application/json');
    try {
      const result = await Ajax.getPromiseJSON(url, HTTPMethodType, headerMap);
      alert(result);
    } catch (error) {
      alert(error);
    }
  }
}

window.onload = function () {
  Main.start();
};

ajax.js

export default class Ajax {
  static getPromiseJSON(url, HTTPMethodType, headerMap) {
    const promise = new Promise(((resolve, reject) => {
      const handler = function () {
        if (this.status >= 200 && this.status <= 299) {
          resolve(this.response);
        } else if (this.status >= 300 && this.status <= 399) {
          reject(new Error(`${this.status} = Redirects!`));
        } else if (this.status >= 400 && this.status <= 499) {
          reject(new Error(`${this.status} = Client Error!`));
        } else if (this.status >= 500 && this.status <= 599) {
          reject(new Error(`${this.status} = Server Error!`));
        }
      };
      const client = new XMLHttpRequest();
      client.open(HTTPMethodType, url);
      headerMap.forEach((value, key) => {
        client.setRequestHeader(key, value);
      });
      client.onload = handler;
      client.send();
    }));
    return promise;
  }

  static async getAsyncJSON(url, HTTPMethodType, headerMap) {
    const response = await Ajax.getPromiseJSON(url, HTTPMethodType, headerMap);
    return response;
  }
}

最后,es6我也是才学习不久的入门小白,如果有阐述不对的地方或者是由更好的见解欢迎评论区留言,一起交流,共同进步!

猜你喜欢

转载自blog.csdn.net/asd0356/article/details/105757389