• ES6知识总结


    感兴趣的朋友可以去我的语雀平台进行查看更多的知识。
    https://www.yuque.com/ambition-bcpii/muziteng

    1. ES6&7&8

    1.1 简介

    1. 什么是ECMA

    ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电

    信和计算机标准,1994 年后该组织改名为Ecma国际

    1. 什么是ECMAScript

    ECMAScript是由Ecma国际通过ECMA-262标准化的脚本程序设计语言。

    image-20220912130857203

    1. 什么是ECMA-262

    Ecma国际制定了许多标准,而ECMA-262只是其中的一个,所有标准列表查看:http://www.ecma-international.org/publications/standards/Standard.htm

    ECMA-262历史版本查看网址: http://www.ecma-international.org/publications/standards/Ecma-262-arch.htm

    • ES5 是 ECMAScript 第5版,2009年发布
    • ES6 是 ECMAScript 第6版,2015年发布,也叫 ES2015
    • 从 ES6 开始,每年发布一个版本,版本号比年份最后一位大 1
    1. 谁在维护ECMA-262

    TC39(Technical Committee 39)是推进ECMAScript 发展的委员会。其会员都是公司(其中主要是浏览器厂商,有苹果、谷歌、微软、

    因特尔等)。TC39 定期召开会议,会议由会员公司的代表与特邀专家出席。

    1. 为什么要学习ES6
    • ES6 的版本变动内容最多,具有里程碑意义
    • ES6 加入许多新的语法特性,编程实现更简单、高效
    • ES6 是前端发展趋势,就业必备技能
    1. ES6兼容性

    可查看兼容性:http://kangax.github.io/compat-table/es6/

    1.2 ECMASript 6 新特征

    1.2.1 let关键字

    let关键字用来声明变量,使用let声明的变量有几个特点

    • 不允许重复声明
    • 块级作用域
    • 不存在变量提升
    • 不影响作用域链
    // 声明变量
    let a;
    let b, c, d;
    let e = 100;
    let f = 521, g = 'iloveyou', h = [];
    
    // 1. 变量不能重复声明
    let str = "你好";
    // let str = "Hello";    // 错误
    
    // 2. 块级作用域  全局,函数,eval
    // if else while for 等都是块级作用域
    // {
    //     let girl = "Cindy";
    // }
    // console.log(girl) // girl is not defined
    
    // 3. 不存在变量提升
    // console.log(song);
    // var song = '恋爱达人';  // 用var可以变量提升
    
    // 用let不可以
    // console.log(test)
    // let test = "test";  // Cannot access 'test' before initialization
    
    // 4. 不影响作用域链
    {
        let school = "你好"
    
        function fn() {
            console.log(school);
        }
    
        fn();
    }
    
    • 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
    • 34
    • 35
    1.2.2 const关键字

    const 关键字用来声明常量,const 声明有以下特点

    • 声明必须赋初始值
    • 标识符一般为大写
    • 不允许重复声明
    • 值不允许修改
    • 块级作用域

    注意:对象属性修改和数组元素变化不会出发 const 错误 应用场景:声明对象类型使用 const,非对象类型声明选择 let

    const arr = ['UZI', "LetMe", "ClearLove7"]
    arr.push("Mekio");
    const obj = {
        name: "Teng",
        age: 20,
    };
    obj.age = 18;   // 不会报错
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1.2.3 变量的解构赋值
    /**
     * ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为 解构赋值
     */
    // 数组的解构赋值
    const arr = ['red', 'green', 'blue'];
    let [r, g, b] = arr;
    console.log(r, g, b);   // red green blue
    // 对象的解构赋值
    const obj = {
        name: "Teng",
        age: 20,
        sayHi() {
            console.log("Hi");
        },
        sayBye() {
            console.log("Bye");
        }
    }
    let {name, age, sayHi} = obj;
    console.log(name, age)  // Teng 20
    sayHi();    // Hi
    let {sayBye} = obj;
    sayBye(); // Bye
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    应用场景:频繁使用对象方法、数组元素,就可以使用解构赋值形式

    1.2.4 模板字符串

    模板字符串(template string)是增强版的字符串,用反引号 ` 标识,特点

    • 字符串中可以出现换行符
    • 可以使用 ${xxx} 形式输出变量,近似 EL 表达式

    应用场景:当遇到字符串与变量拼接的情况使用模板字符串

    let name = "Teng"
    console.log(`hello, ${name}`);
    
    let ul = `
    • apple
    • banana
    • peach
    `
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1.2.5 简化对象写法

    ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁

    应用场景:对象简写形式简化了代码,所以以后用简写就对了

    {
        let name = "Teng";
        let age = 20;
        let sayHi = function () {
            console.log("Hi")
        }
        }
    
    // 创建对象 因属性、方法的 k v 同名,可以简化
    const obj = {
        name: "Teng",
        age: 20,
        sayHi() {
            console.log("Hi")
        }
    };
    let {name, age, sayHi} = obj;
    console.log(name, age);
    sayHi();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    1.2.6 箭头函数

    ES6 允许使用箭头=>定义函数

    let fn = (param1, param2,, paramN) => {
        // 函数体
        return expression;
    }
    
    • 1
    • 2
    • 3
    • 4

    注意

    • 如果形参只有一个,小括号可以省略
    • 如果函数体只有一条语句,花括号可以省略,函数的返回值为该条语句的执行结果,如果是 return 语句,return 必须省略
    • 箭头函数 this 是静态的,始终指向声明时所在作用域下 this 的值
    • 箭头函数不能作为构造函数实例化
    • 不能使用 arguments
    let fn1 = function () {
    }
    let fn2 = (a, b) => {
        return a + b;
    }
    // 调用函数
    // console.log(fn2(1, 2))
    
    // 1. this是静态的 this始终指向函数声明时所在作用域下的this的值
    const obj = {
        a: 10,
        getA() {
            let fn3 = () => {
                console.log(this);  // obj 这个对象
                console.log(this.a);    // 10
            }
            fn3();
        }
    }
    obj.getA()
    
    function getName() {
        console.log(this.name);
    }
    
    let getName2 = () => {
        console.log(this.name);
    }
    // 设置window对象的name属性
    window.name = "Teng"
    const school = {
        name: "MuZi"
    }
    // 直接调用
    //getName()   // Teng
    //getName2()  // Teng
    
    // call方法调用
    //getName.call(school);   // MuZi
    //getName2.call(school);  // Teng
    
    
    // 2. 不能作为构造函数实例化对象
    // let Person = (name, age) => {
    //     this.name = name;
    //     this.age = age;
    // }
    // let me = new Person("Teng", 20);
    // console.log(me) // Person is not a constructor
    
    // 3. 不能使用arguments变量
    // let f = () => {
    //     console.log(arguments); // arguments is not defined
    // }
    // f(1, 2, 3);
    
    • 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
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    1.2.7 函数参数默认值设定

    ES6 允许给函数参数设置默认值,当调用函数时不给实参,则使用参数默认值

    具有默认值的形参,一般要靠后。

    let add = (x, y, z=3) => x + y + z;
    console.log(add(1,2));	// 6
    
    • 1
    • 2

    可与解构赋值结合

    function connect({host = '127.0.0.1', username, password, port}) {
        console.log(host)
        console.log(username)
        console.log(password)
        console.log(port)
    }
    
    connect({
        // host: "www.baidu.com",
        username: "root",
        password: "root",
        port: 3306
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1.2.8 rest 参数

    ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments,作用与 arguments 类似,将接收的参数序列转换为一个数组对象

    (arguments 是伪数组)

    语法格式:fn(a, b, ...args),写在参数列表最后面

    应用场景:rest 参数非常适合不定个数参数函数的场景

    let fn = (a, b, ...args) => {
        console.log(a);
        console.log(b);
        console.log(args);
    }
    fn(1, 2, 3, 4, 5);
    // 1
    // 2
    // (3) [3,4,5]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1.2.9 spread 扩展运算符

    扩展运算符spread也是三个点...,它好比 rest 参数的逆运算,将一个数组、伪数组转为用逗号分隔的参数序列,对数组进行解包,扩

    展运算符也可以将对象解包 ,可用在调用函数时,传递的实参,将一个数组转换为参数序列(与rest参数的区别,一个用在形参,一个实

    参)

    展开数组

    function fn(a, b, c) {
        console.log(arguments)
        console.log(a + b + c)
    }
    let arr = ['red', 'green', 'blue'];
    fn(...arr);
    // Arguments(3) {'0': 'red', '1': 'green', '2': 'blue'}
    // redgreenblue
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    案例:数组合并

    let A = [1, 2, 3];
    let B = [4, 5, 6];
    let C = [...A, ...B];
    console.log(C); // [1,2,3,4,5,6]
    
    • 1
    • 2
    • 3
    • 4

    案例:对象合并

    let obj1 = {
        a: 123
    }
    let obj2 = {
        b: 456
    }
    let obj3 = {
        c: 789
    }
    let obj = {...obj1, ...obj2, ...obj3};
    console.log(obj)    // {a:123,b:456,c:789}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1.2.10 Promise

    Promise是 ES6 引入的异步编程的新解决方案,语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果

    一个Promise必然处于以下几种状态之一

    • 待定pending:初始状态,既没有被兑现,也没有被拒绝
    • 已兑现fulfilled:意味着操作成功完成
    • 已拒绝rejected:意味着操作失败

    Promise的使用

    • Promise构造函数new Promise((resolve, reject) => {})
    • Promise.prototype.then()方法
    • Promise.prototype.catch()方法
    let p = new Promise((resolve, reject) => {
        // 使用setTimeout模拟请求数据库
        setTimeout(() => {
            let isRight = true; // 这个异步请求数据库数据操作是否正确返回数据
            if (isRight) {
                let data = '数据库中的数据'
                resolve(data);  // 设置 Promise 对象的状态为操作成功
            } else {
                let err = '数据读取失败';
                reject(err);    // 设置 Promise 对象的状态未操作失败
            }
        }, 2000)
    })
    p.then(function (value) {
        console.log(value)
    }, function (reason) {
        console.error(reason);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    Promise封装读取文件

    // 使用node.js 的 fs 读取文件模块
    const fs = require('fs');
    
    const p = new Promise((resolve, reject) => {
        fs.readFile('./aaa.txt', (err, data) => {
            if (err) reject(err);
            resolve(data);
        })
    })
    p.then((value) => {
        console.log(value.toString())
    }, reason => {
        console.log("读取失败")
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    Promise 封装 Ajax 请求

    const p = new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open('get', 'https://api.apiopen.top/getJoke');
        xhr.send();
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    resolve(xhr.response);  // 成功
                } else {
                    reject(xhr.status); // 失败
                }
            }
        }
    })
    
    // 指定回调
    p.then((value) => {
        console.log(value)
    }, (reason) => {
        console.log(reason)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    Promise.prototype.then 方法

    Promise.prototype.then方法返回的结果依然是Promise对象,对象状态由回调函数的执行结果决定

    具体情况如下

    • then方法未写返回值,则then方法返回的对象的状态值为成功fulfilled,返回结果值为undefined
    const p = new Promise((resolve, reject) => {
        setTimeout(() => {
            // resolve('用户数据')
            reject("出错了")
        }, 1000);
    })
    // 未设定返回值
    const res = p.then((value) => {
        console.log(value);
    }, (reason) => {
        console.log(reason)
    })
    // 打印then方法的返回值
    console.log(res)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    image-20220920085609311

    • 如果回调函数中返回的结果是非Promise类型的属性,则then方法返回的对象,其状态为成功fulfilled,返回结果值取决于

      then方法所执行的是哪个函数(resolvereject

    const p = new Promise((resolve, reject) => {
        setTimeout(() => {
            // resolve('用户数据')
            reject("出错了")
        }, 1000);
    })
    // 返回的非Promise对象
    const res = p.then((value) => {
        console.log(value)
        return "成功了"
    }, (reason) => {
        console.warn(reason)
        return "出错了"
    })
    // 打印then方法的返回值
    console.log(res)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    image-20220920085857306

    • 如果回调函数中返回的结果是Promise类型return new Promise(),则then方法返回的Promise对象状态与该返回结果的状态相

      同,返回值也相同

    const p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('用户数据')
            // reject('出错了');
        }, 1000);
    })
    const res = p.then((value) => {
        console.log(value);
        // 返回 Promise 对象
        return new Promise((resolve, reject) => {
            resolve('(1)成功了!!!');
            // reject('(1)出错了!!!')
        })
    }, (reason) => {
        console.warn(reason);
        return new Promise((resolve, reject) => {
            // resolve('(2)成功了!!!');
            reject('(2)出错了!!!')
        })
    })
    // 打印 then 方法的返回值
    console.log(res);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    image-20220920085951875

    • 如果回调函数中返回的结果是throw语句抛出异常,则then方法的对象的状态值为rejected,返回结果值为throw抛出的字面量

      或者Error对象

    const p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('用户数据');
        }, 1000);
    });
    const res = p.then((value) => {
        console.log(value);
        return new Promise((resolve, reject) => {
            throw new Error('错误了!!');
        })
    });
    // 打印结果
    console.log(res);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    image-20220920090026465

    链式调用

    Promise.prototype.then方法返回的结果还是Promise对象,这意味着我们可以继续在该结果上使用then方法,也就是链式调用。

    const p = new Promise(resolve=>{}, reject=>{});
    p.then(value=>{}, reason=>{})
    .then(value=>{}, reason=>{})
    .then(value=>{}, reason=>{})
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Promise.prototype.catch

    catch()方法返回一个Promise,并且处理拒绝的情况,它的行为与调用Promise.prototype.then(undefined, onRejected)相同

    obj.catch(onRejected);
    等同于
    obj.then(undefined, onRejected);
    
    • 1
    • 2
    • 3

    语法

    p.catch(onRejected);
    
    p.catch(function(reason) {
       // 拒绝
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5

    举例

    var p1 = new Promise(function (resolve, reject) {
        resolve('Success');
    });
    
    p1.then(function (value) {
        console.log(value); // "Success!"
        throw 'oh, no!';
    }).catch(function (e) {
        console.log(e); // "oh, no!"
    }).then(function () {
        console.log('有 catch 捕获异常,所以这句输出');
    }, function () {
        console.log('没有 catch 捕获异常,这句将不会输出');
    });
    
    // 结果
    Success
    oh, no!
    有 catch 捕获异常,所以这句输出
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    1.2.11 Set

    ES6 提供了新的数据结构Set(集合),它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用扩展运算符 …

    和 for…of 进行遍历。

    属性和方法

    • st.size:返回集合个数
    • st.add(item):往集合中添加一个新元素 item,返回当前集合
    • st.delete(item):删除集合中的元素,返回 boolean 值
    • st.has(item):检测集合中是否包含某个元素,返回 boolean 值
    • st.clear():清空集合
    • 集合转为数组:[…st]
    • 合并两个集合:[…st1, …st2]
    // 数组去重
    let arr1 = [1, 2, 2, 3, 3, 3, 4, , 1, 2];
    let res1 = [...new Set(arr1)]
    console.log(res1) // [1,2,3,4]
    // 数组求交集
    let arr2_1 = [1, 2, 2, 3, 4, 5];
    let arr2_2 = [3, 6, 6, 7, 1, 4]
    let res2 = arr2_1.filter(arr => new Set(arr2_2).has(arr));
    console.log(res2) // [1,3,4]
    // 数组求并集
    let arr3_1 = [1, 2, 2, 3, 4, 5];
    let arr3_2 = [3, 6, 6, 7, 1, 4];
    let res3 = [...new Set([...arr3_1, ...arr3_2])];
    console.log(res3)   // [1,2,3,4,5,6,7]
    // 求差集
    let arr4_1 = [1, 2, 2, 3, 4, 5];
    let arr4_2 = [3, 6, 6, 7, 1, 4];
    let res4 = [...new Set(arr4_1)].filter(v => !(new Set(arr4_2).has(v)));
    console.log(res4)   // [2,5]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    1.2.12 Map

    ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是 “键” 的范围不限于字符串,各种类型的值(包括对象)都可以当作

    键。Map 也实现了 iterator 接口,所以可以使用扩展运算符 … 和 for…of 进行遍历

    Map 的属性和方法:(k 为键,v为值)

    • size:返回 Map 的元素(键值对)个数
    • set(k, v):增加一个键值对,返回当前 Map
    • get(k):返回键值对的键值
    • has():检测 Map 中是否包含某个元素
    • clear():清空集合,返回 undefined
    let map = new Map();
    
    map.set('name', 'Teng');
    map.set('change', function () {
        console.log("Change");
    })
    let key = {
        school: "CQJTU"
    }
    map.set(key, ['深圳', '重庆']);
    console.log(map.size)
    map.delete('name')
    console.log(map.get('change'))
    console.log(map.get(key))
    for (const element of map) {
        console.log(element)
    }
    map.clear()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    1.2.13 模块化

    模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来

    模块化的优势有以下几点

    • 防止命名冲突
    • 代码复用
    • 高维护性

    语法

    模块功能主要由两个命令构成

    • export命令用于规定模块的对外接口
    • import命令用于输入其他模块提供的功能

    模块导出数据语法

    // 1. 分别暴露
    export let school = 'CQJTU';
    
    export function teach() {
        console.log("哈哈哈哈哈哈哈");
    }
    
    // 2. 统一暴露
    let school = 'CQJTU';
    function findJob() {
        console.log("你好");
    }
    
    export {school, findJob};
    
    // 3. 默认暴露
    export default {
        school: 'CQJTU',
        change() {
            console.log("Change");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    模块导入数据语法

    // 1. 通用导入方式
    import * as m1 from './js/m1.js';
    import * as m2 from './js/m2.js';
    import * as m3 from './js/m3.js';
    
    m3.default.change()
    
    // 2. 解构赋值导入
    import {school, teach} from "./src/js/m1.js";
    import {school as guigu, findJob} from "./src/js/m2.js";
    import {default as m3} from "./src/js/m3.js";
    
    // 3. 简便方式导入,只能用于默认暴露
    import m3 from "./src/js/m3.js";
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    1.3 ECMASript 7 新特性

    1.3.1 Array.prototype.includes

    includes 方法用来检测数组中是否包含某个元素,返回布尔类型值

    const arr = [1, 2, 3];
    console.log(arr.includes(1)) // true
    
    • 1
    • 2
    1.3.2 指数运算符

    在 ES7 中引入指数运算符 **,用来实现幂运算,功能与 Math.pow(a, b) 结果相同

    // includes   indexOf也可以判断
    const mingzhu = ['西游记','红楼梦','三国演义','水浒传'];
    
    //判断
    console.log(mingzhu.includes('西游记'));    // true
    console.log(mingzhu.includes('金瓶梅'));
    
    // **
    console.log(2 ** 10);	// 1024
    console.log(Math.pow(2, 10));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    1.4 ECMAScript 8 新特性

    1.4.1 async 和 await

    asyncawait两种语法结合可以让异步代码像同步代码一样(看起来是同步的,实质上是异步的)

    先从字面意思理解,async意为异步,可以用于声明一个函数前,该函数是异步的。await意为等待,即等待一个异步方法完成。

    async

    asyncfunction变为成为async函数

    • async内部可以使用await,也可以不使用,因此执行这个函数时,可以使用thencatch方法
    • async函数的返回值是一个Promise对象
    • Promise对象的结果由async函数执行的返回值决定
    async function funcName() {
        //statements 
    }
    
    • 1
    • 2
    • 3
    • 函数体不return 返回值,则async函数返回值为一个成功fulfilledPromise对象,值为undefined
    let a = async function() {}
    let res = a()
    console.log(res) // Promise{: undefined}
    
    • 1
    • 2
    • 3
    • return结果不是一个Promise,则async函数返回值为一个成功fulfilledPromise对象,状态值为这个内部返回值
    let a = async function () {
      return 'hello'
    }
    let res = a()
    console.log(res) // Promise{: 'hello'}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 内部抛出错误,则async函数返回值为一个失败rejectPromise对象
    let a = async function foo() {
      throw new Error('出错了')
    }
    a().catch(reason => {
      console.log(reason)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 若函数内部返回值是一个Promise对象,则async函数返回值的状态取决于这个Promise对象是resolve还是reject
    let a = async function () {
      return new Promise((resolve, reject) => {
        resolve("成功")
      })
    }
    a().then(value => {
      console.log(value)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    await

    await相当于一个运算符,右边接一个值。一般为一个Promise对象,也可以是一个非Promise类型。

    • 当右接一个非promise类型,await表达式返回的值就是这个值;当右接一个promise对象,则await表达式会阻塞后面的代码,

      等待当前promise对象resolve 的值

    综合asyncawait而言

    • await必须写在async函数中
    • await右侧的表达式一般为promise对象
    • await返回的是promise成功的值
    • awaitpromise失败了就会抛出异常,需要使用try-catch捕获处理
    • Promise使用链式调用解决了传统方式回调地狱的问题,而async-await又进一步优化了代码的可读性
    // 创建 promise 对象
    const p = new Promise((resolve, reject) => {
      // resolve("用户数据");
      reject("失败啦!");	// 设置状态跟值
    })
    
    // await 要放在 async 函数中.
    async function main() {
      try {
        let result = await p;	// 成功的值
        console.log(result);
      } catch (e) {
        console.log(e);	// 失败的值
      }
    }
    // 调用函数
    main();	// '失败'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    论文摘要的写作技巧
    山西电力市场日前价格预测【2023-09-07】
    因果推断 之 初介绍 + 案例分析
    造个Python轮子,实现根据Excel生成Model和数据导入脚本
    yum升级mysql
    展会动态 | 迪捷软件邀您参加2023世界智能网联汽车大会
    配置Insecure Docker Registry支持http请求 (更改默认的https请求)
    PHP开发工具:打造高效的编码体验
    Linux操作系统——面试题-(腾讯,百度,美团,滴滴)
    Android Studio 中AGP ,Gradle ,JDK,SDK都是什么?
  • 原文地址:https://blog.csdn.net/m0_52781902/article/details/126947891