• ES6 Promise、Generator与async简单介绍与应用


    在项目开发中难免会遇到异步的问题,最原始的做法就是函数嵌套,但是这样难免会造成函数的地狱回调,于是我们可使用异步来解决这些问题。


    那么什么是异步呢?

    所谓"异步",简单说就是一个任务不是连续完成的,可以理解成该任务被人为分成两段,先执行第一段,然后转而执行其他任务,等做好了准备,再回过头执行第二段。

    比如,有一个任务是读取文件进行处理,任务的第一段是向操作系统发出请求,要求读取文件。然后,程序执行其他任务,等到操作系统返回文件,再接着执行任务的第二段(处理文件)。这种不连续的执行,就叫做异步。

    相应地,连续的执行就叫做同步。由于是连续执行,不能插入其他任务,所以操作系统从硬盘读取文件的这段时间,程序只能干等着。


    一.简单介绍:


    1.Promise:

    概念:

    Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。

    所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

    特点:

    Promise有三种状态,分别是:

    1. pending(进行中);
    2. fulfilled(已成功);
    3. rejected(已失败)

    基本语法:

    const promise = new Promise(function(resolve, reject) {
      // ...
      if (/* 成功 */){
        resolve(value);
      } else {
        reject(error);
      }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.Generator

    概念:

    Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。

    Generator 函数有多种理解角度。语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态。

    执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。

    特点:

    形式上,Generator 函数是一个普通函数,但是有两个特征。

    1. function关键字与函数名之间有一个星号;
    2. 函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。

    基本语法:

    function* first_generator() {
      yield '1';
      yield '2';
      return '3';
    }
    
    var fg = first_generator();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.async

    概念:

    ES2017 标准引入了 async 函数,使得异步操作变得更加方便。

    async 函数是什么?它就是 Generator 函数的语法糖。

    async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已。

    基本语法:

    // 函数声明
    async function foo() {}
    
    // 函数表达式
    const foo = async function () {};
    
    // 对象的方法
    let obj = { async foo() {} };
    obj.foo().then(...)
    
    
    // 箭头函数
    const foo = async () => {};
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    二.基本使用

    1.原始写法:

    在函数进行嵌套的时候,会形成如下代码:

    function add() {
         fn(...){
    		fn(...){...}
    	}    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在上一个完成后接着执行下一个,少量还好万一处理事件一多,代码维护性就会变差,逻辑就会看起来很乱。

    2.Promise:

    var a = 10,b=20
    const promise = new Promise((resolve,reject)=>{
    	if (/* 异步操作成功 */){
        	resolve(value);
      	} else {
        	reject(error);
        }
    })
    
    promise.then((res)=>{
       .....
    }).then((res1)=>{
       ....
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    相对于原始写法来说确实思维很清晰,也方便我们的维护。

    3.Generator:

    function * gen(){
        yield '123'
        yield '234'
        yield '456'
    }
    
    var _g=gen()
    
    console.log(_g.next().value);
    console.log(_g.next().value);
    console.log(_g.next().value);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    注意:虽然_g.next().value写法一样,但是执行的结果不一样,如下图所示:
    在这里插入图片描述

    4.async:

    const async_a = async function () {
        const f1 = await console.log(123);;
        const f2 = await console.log(234);;
    };
    
    async_a()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    async返回 Promise 对象,正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。

    async function f() {
        // 等同于
        // return 123;
        return await 123;
    }
      
    f().then(v => console.log(v))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

  • 相关阅读:
    国内券商有没有提供股票量化交易,程序化交易接口的,怎么用?
    远程访问服务器JupyterLab的配置方法
    中秋《乡村振兴战略下传统村落文化旅游设计》许少辉八月新书——2023学生思乡季辉少许
    Spark基础【两个小案例、Yarn模式下任务执行源码】
    CSS box-shadow阴影
    drools项目中dmn文件调用自定义的java类
    【最佳实践】瀚高数据库企业版v6.0.2在Centos7.8安装过程
    QT学习_02_Lambda表达式——槽函数的正确打开方式
    Oracle查询表全部唯一约束(唯一键)
    spring创建bean方式
  • 原文地址:https://blog.csdn.net/qq_45096273/article/details/125997982