• ES6(三)


    Promise

    概念

    Promise 是异步编程的一种解决方案,比传统的解决方案回调函数, 更合理和更强大。ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象

    作用

    • 指定回调函数方式更灵活易懂。

    • 解决异步 回调地狱 的问题。

    回调地狱

    • 当一个回调函数嵌套一个回调函数的时候

    • 就会出现一个嵌套结构

    • 当嵌套的多了就会出现回调地狱的情况

    • 比如我们发送三个 ajax 请求

      • 第一个正常发送
      • 第二个请求需要第一个请求的结果中的某一个值作为参数
      • 第三个请求需要第二个请求的结果中的某一个值作为参数
    ajax({
      url: '我是第一个请求',
      success (res) {
        // 现在发送第二个请求
        ajax({
          url: '我是第二个请求'data: { a: res.a, b: res.b },
          success (res2) {
            // 进行第三个请求
            ajax({
              url: '我是第三个请求',
              data: { a: res2.a, b: res2.b },
      				success (res3) { 
                console.log(res3) 
              }
            })
          }
        })
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    Promise使用

    new Promise(function (resolve, reject) {
      // resolve 表示成功的回调
      // reject 表示失败的回调
    }).then(function (res) {
      // 成功的函数
    }).catch(function (err) {
      // 失败的函数
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    对象的状态

    Promise 对象通过自身的状态,来控制异步操作。Promise 实例具有三种状态。

    异步操作未完成(pending)
    异步操作成功(fulfilled)
    异步操作失败(rejected)

    这三种的状态的变化途径只有两种。

    一旦状态发生变化,就凝固了,不会再有新的状态变化。这也是 Promise 这个名字的由来,它的英语意思是“承诺”,一旦承诺成效,就不得再改变了。这也意味着,Promise 实例的状态变化只可能发生一次

    一旦状态发生变化,就凝固了,不会再有新的状态变化。这也是 Promise 这个名字的由来,它的英语意思是“承诺”,一旦承诺成效,就不得再改变了。这也意味着,Promise 实例的状态变化只可能发生一次。

    因此,Promise 的最终结果只有两种。

    异步操作成功,Promise 实例传回一个值(value),状态变为fulfilled。
    异步操作失败,Promise 实例抛出一个错误(error),状态变为rejected。

    Promise.all

    Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

    const p = Promise.all([p1, p2, p3]);
    
    • 1

    p的状态由p1,p2,p3 决定,分成两种情况。

    (1)只有p1p2p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数。

    (2)只要p1p2p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

    Promise.race

    Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

    const p = Promise.race([p1, p2, p3]);
    
    • 1

    上面代码中,只要p1p2p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

    Generator 函数

    概念

    Generator 函数是 ES6 提供的一种异步编程解决方案

    Generator 函数是一个状态机,封装了多个内部状态。

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

    基本语法

    function *gen(){
        console.log(1)
        yield;
        console.log(2)
        yield;
        console.log(3)
    }
    
    let g = gen()
    g.next()
    g.next()
    g.next()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    yield(产出)表达式是暂停执行的标记,而next方法可以恢复执行。

    function *gen(){
        yield  1;
        yield  2;
    }
    
    let g = gen()
    let res1 = g.next()
    console.log(res1)
    let res2 = g.next()
    console.log(res2)
    let res3 = g.next()
    console.log(res3)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    function *gen(){
        let res1 = yield;
        console.log(res1)
        let res2 = yield;
        console.log(res2)
    }
    
    let g = gen()
    g.next("data-1")
    g.next("data-2")
    g.next("data-3")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    异步流程

    手动版本

    function *gen(){
        let res1 = yield ajax("1.json")
        console.log(res1)
        let res2 = yield ajax("2.json")
        console.log(res2)
    }
    
    let g = gen()   
    
    g.next().value.then(data=>{
        g.next(data).value.then(data=>{
            g.next(data)
        })
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    自动版本

    function* gen() {
        let res1 = yield ajax("1.json")
        console.log(res1)
        let res2 = yield ajax("2.json")
        console.log(res2)
    }
    
    
    function AutoRun(gen) {
        let g = gen();
    
        function next(data) {
            let res = g.next(data);
            if (res.done) return 
            res.value.then(function (data) {
                next(data);
            });
        }
    
        next();
    }
    
    AutoRun(gen);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    Class语法

    类的写法

    class Person {
        constructor(name,age){
            this.name = name;
            this.age = age;
        }
        say(){
            console.log(this.name,this.age)
        }
    }
    let obj = new Person("kerwin",100)
    console.log(obj)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    getter与setter

    class List{
        constructor(ele){
            this.element = ele
        }
    
        get html(){
            return this.element.innerHTML
        }
        set html(arr){
            this.element.innerHTML = arr.map(item=>`
  • ${item}
  • `
    ).join("") } } let obj = new List(document.querySelector("#list")) obj.html = ["aaa","bbb","cccc"]
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    静态属性和静态方法

     class Person {
        static name = "Person这个类"
        constructor(name,age){
            this.name = name;
            this.age = age;
        }
        say(){
            console.log(this.name,this.age)
        }
    
        static eat(){
            console.log("eat")
        }
    }
    let obj = new Person("kerwin",100)
    
    console.log(Person.name)
    Person.eat()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    继承

    ES6 规定,子类必须在constructor()方法中调用super(),否则就会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,添加子类自己的实例属性和方法。如果不调用super()方法,子类就得不到自己的this对象。

    class Person {
        static name = "Person这个类"
        constructor(name,age){
            this.name = name;
            this.age = age;
        }
        say(){
            console.log(this.name,this.age)
        }
    
        static eat(){
            console.log("eat")
        }
    }
    class Student extends Person{
        constructor(name,age,score){
            super(name,age)
            this.score = score
        }
        say(){
            super.say()
            console.log(this.score)
        }
    
        static eat(){
            super.eat();
            console.log("student eat")
        }
    }
    let obj = new Student("kerwin",100,200)
    console.log(obj)
    obj.say()
    Student.eat()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    模块化

    JavaScript 现在有两种模块。一种是 ES6 模块,简称 ESM;另一种是 CommonJS 模块,简称 CJS。

    CommonJS 模块是 Node.js 专用的,与 ES6 模块不兼容。语法上面,两者最明显的差异是,CommonJS 模块使用require()module.exports,ES6 模块使用importexport
    写法1:

    export default A1
    
    import a1 from "./1.js"
    
    • 1
    • 2
    • 3

    写法2:

    export {A1,A2}
    
    import {A1,A2} from "./1.js"
    
    import {A1 as a1,A2 as a2} from "./1.js"
    
    import * as obj from "./1.js"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    export function A1(){
        console.log("A1")
    }
    export function A2(){
        console.log("A2")
    }
    
    
    import {A1,A2} from "./1.js"
    
    import {A1 as a1,A2 as a2} from "./1.js"
    
    import * as obj from "./1.js"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    混合写法:

    export {A1}
    export default A2
    
    import A2,{A1} from "./1.js"
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    Chrome实现自动化测试:录制回放网页动作
    初学yolov5。
    【BOOST C++ 20 设计模式】(2)库Boost.Signals2
    2022前端面试题上岸手册-性能优化部分
    C++对象内存故事, 一个对象是如何由子对象来构成的?
    谷粒商城九商品服务商品基本概念与属性分组todo
    高电压技术-冲击高压发生器MATLAB仿真
    【机器学习 | Python】mlxtend 包的使用指南
    【Scala专栏】数据类型、变量常量、类和对象
    目标检测YOLO实战应用案例100讲-基于YOLOv5的航拍图像旋转目标检测
  • 原文地址:https://blog.csdn.net/2202_75345049/article/details/132536641