Hz零基础学习ES6

1、ES6

ES6是什么?

 ECMAScript6.0(ES6)是JavaScript语言下一代的标准,已经在2015年6月正式发布。它的目标是使得JavaScript语言可以编写复杂的大型应用。

ECMAScript与JavaScript区别?

 ECMAScript是一种标准规范,JavaScript是ECMAScript的具体实现。

ES6与ECMAScript2015的关系?

 ES6在2015年6月份正式发布,正式名称就是《ECMAScript2015标准》简称ES2015。
 ES6 == ECMAScript2015
 以后在每年的6月份将会发布一个新版本,将会已年份命名为版本号。(ES2016 ES2017)

总结:
  ES6是一个历史名词,也是一个泛指,含义是5.1版本之后的JavaScript的下一代标准,涵盖了ES2015、
ES2016、ES2017等。而ES2015则是正式名称,特指该年发布的正式版本的语言标准。

2、Babel 

Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,
以便能够运行在当前和旧版本的浏览器或其他环境中。



babel无法转义一些API
babel默认只转义新标准引入的语法,比如ES6的箭头函数,不转移新的API,比如:iterator、Set、Map、Promise等全局对象。

解决方法: 使用babel-polyfill   为当前环境提供一个垫片.

npm install --save babel-polyfill

3、let  const var

let const 是ES6中提出的变量声明

let与const的特点一样。只不过let是用来声明变量的而const是用来声明常量的。

var存在的问题:
         1.全局作用域
         2.存在变量提升
         3.可重复声明


let const特点:
         1.局部作用域
         2.不可重复声明(同一作用域)
         3.没有变量提升
   
const特性:
     1.使用const必须赋值。
     2.如果值是基本数据类型,则值不能改动。
     3.如果const声明的是对象类型,其保存的是对象的地址,const只能保证地址不发生改变,
     却不能保证该对象的值不发生改变。所以使用const时需要注意数值的类型。
     onConst() {
      //const a; //报错
      const a = 10;
      a = 100; //值不可改动
    }



   问题代码案列:

    //使用var 定义的变量是全局变量,预期我们想要的是局部声明
    for (var i = 0; i < 10; i++) {}
    console.log(i); //10

    //重复声明 变量提升问题
    onStatement() {
      /*
      使用var定义 此处只会抛出undefined 而不是我们预期的报错
      JS实际上将代码声明提到了前面
        var b;
        console.log(b);
        b = 5;
     */
      console.log(b); //undefined
      var b = 5;
      var b = 6; //重复声明不报错
    },


    //使用let解决重复声明 变量提升问题
    onStatementLet() {
      /** 无bable引入便会抛出异常
          Cannot access 'c' before initialization
          否则你将会看到和var等同的效果,bable会将es6的语法转换低级语法。
          let 没有变量提升
          let 无法重复声明变量  
      */
      console.log(c);
      let c = 5;
      //let c = 6;  报错
    }

    

4、Symbol数据类型

ES6之前JS存在的数据类型:

   Number
   String
   Boolean
   Object
   Null
   Undefined

转载:https://www.jianshu.com/p/f40a77bbd74e

5、解构赋值

 

    //解构赋值
    let a, b, c;
    [a, b, c] = [1, 2];
    console.log(a, b, c); //1 2 undefined 未赋值将会赋值undefined
    [a, b, c] = [1, 2, 3];
    console.log(a, b, c); //1 2 3

    let d, arrys;
    [d, ...arrys] = [1, 2, 3, 4, 5];
    console.log(d, arrys); //1  [2, 3, 4, 5](...后将会已数组形式赋值)

    let q, w;
    [q, , w] = [1, 2, 3]; // ,占位符
    console.log(q, w); //1 3

    
    //解构赋值对象
    let t, y;
    ({ t, y } = { t: 123, y: 456 });
    console.log({ t, y }); //{t: 123, y: 456}

    let num, total;
    ({ k: num, j: total } = { k: 123, j: 456 });
    console.log({ num, total }); //{num: 123, total: 456}




    //模拟后台JSON数据 使用解构赋值
    simulationJson() {
      return {
        name: "司大屌",
        age: 23,
        hobby: ["篮球", "lol", "跑步"],
        computer: [{ name: "华硕" }, { name: "小米" }, { name: "苹果" }]
      };
    }, 


    let dataJson = this.simulationJson();
    console.log(dataJson);

    let {
      name: JsonName,
      age: JsonAge,
      hobby: JsonHobby,
      computer: JsonComputer
    } = dataJson;
    //司大屌 23  ["篮球", "lol", "跑步"]  [{…}, {…}, {…}]
    console.log(JsonName, JsonAge, JsonHobby, JsonComputer);

    let {
      name: JName,
      age: JAge,
      hobby: [JHobby], //只取出hobby数组第一个值
      computer: [{ name: JComputerName }] //只取出computer数组第一个对象的name值
    } = dataJson;
    //司大屌 23 篮球 华硕
    console.log(JName, JAge, JHobby, JComputerName);

6、ES6加强Unicode的缺陷

  在ES5中JavaScript允许采用\uxxxx形式表示一个字符,其中xxxx表示字符的unicode码点。
这种表示法只限于码点在\u0000~\uFFFF之间的字符。超出必须用双字节形式表示,但是ES5无法正确识别双字节组成的字符,ES6可以。



  let a = "\u20bb7";
  console.log(a); //₻7  乱码
  let b = "\u{20bb7}";
  console.log(b); //𠮷  ES6中码点用{}包起来


  补充知识点:for-of
  console.log(b.length); //2

  //传统for会将unicode字符识别乱码打印 � �
  for (let i = 0; i < b.length; i++) {
    console.log(b[i]);
  }

  //使用for of 会正确打印出数值 𠮷
  for (let w of b) {
    console.log(w);
  }

  //普通字符串 传统for 与 for-of 效果相同
  let bba = "1234567";
  for (let i = 0; i < bba.length; i++) {
    console.log("传统", bba[i]);
  }

  for (let w of bba) {
    console.log("for-of", w);
  }

7、ES6中新增字符串API和模板字符串

    //ES6字符串API
    let str = "123Ldd321";
    //判断字符串是否包含指定字符串
    console.log("includes字符串包含", str.includes("Ldd")); //true
    //判断字符串的开头是否包含指定字符串,返回值是布尔值
    console.log("startsWith", str.startsWith("123")); //true
    //判断字符串的结尾是否包含指定字符串,返回值是布尔值
    console.log("endsWith", str.endsWith("123")); //false
    //repeat 将一个字符串重复n次
    str = str.repeat(3);
    console.log(str); //123Ldd321123Ldd321123Ldd321

    let b = "大屌";
    //padStart 在字符串开头已指定的字符补全  3代表补全后字符串的长度  "司"指定字符串
    b = b.padStart(3, "司");
    console.log(b); //司大屌

    //如果补全后的字符串长度小于补全前的 将不会执行
    b = b.padStart(1, "司");
    console.log(b); //司大屌

    //padEnd 在字符串后面补全
    b = b.padEnd(5, "游戏");
    console.log(b); //司大屌游戏
    let name = "司大屌";
    let str = `我叫${name},今年${this.onReturnAge()}  反引号使用转义符 \``;
    console.log(str);//我叫司大屌,今年23  反引号使用转义符 `


    onReturnAge() {
      return 23;
    },

  
    注意:
      1.在模板字符串中使用反引号需要用到转义符
      2.在模板字符串中所有的空格和缩进符将会被保存输出
      3.在模板字符串中使用变量,必须${变量名}方式引入
      4.在模板字符串中${...}大括号中可以放入任意的JavaScript表达式

8、ES6数组操作

    //数组扩展运算符使用

    //1.浅拷贝(复制数组)
    let list = [1, 2, 3, 4];
    let list2 = [...list];
    console.log(list2); //[1, 2, 3, 4]

    //2.分割数组
    let baseList = [1, 2, 3, 4];
    let [, ...newList] = baseList; //,占位符跳过第一个数据
    console.log(newList); //[2, 3, 4]

    //3.方法传参
    let addList = [1, 2];
    console.log(this.addTwoData(...addList)); //3

    addTwoData(x, y) {
      return x + y;
    },

    //fill 填充数据 数组是引用类型

    let fillList = [1, 2, 3, 4, 5];
    let fillList2 = fillList.fill(3); //将数组中所有的元素替换成3
    console.log(fillList == fillList2); //true  fill改变原数组的值 只不过将地址复制。可参考下面浅拷贝
    console.log(fillList2); // [3, 3, 3, 3, 3]

    let fillListT = [1, 2, 3, 4, 5];
    let fillList3 = fillListT.fill(3, 1, 4); // 3 需要替换的值  1起始下标(包含) 4结束下标(不包含)
    console.log(fillList3); //[1, 3, 3, 3, 5]

    //浅拷贝使用fill 不会改变baseListFill
    let baseListFill = [1, 2, 3, 4];
    let baseListFill2 = [...baseListFill].fill(2);
    console.log(baseListFill); //[1, 2, 3, 4]
    console.log(baseListFill2); //[2, 2, 2, 2]
    //find  findIndex
    const list = [
      { name: "张三", id: 1 },
      { name: "李四", id: 2 },
      { name: "王五", id: 3 },
      { name: "张三", id: 4 }
    ];
    //注意find 会找到首先找到第一个
    let listF = list.find(function(item) {
      return item.name === "张三";
    });
    console.log(listF); //{name: "张三", id: 1}

    let listFIndex = list.findIndex(function(item) {
      return item.name === "张三";
    });
    console.log(listFIndex); //0 返回下标

    //includes只能检测基本数据类型返回boolean  比indexOf 方便
    const bList = [1, 2, 3, 4, 5];
    let iB = bList.includes(2);
    console.log(iB); //true

    //flat 展开内嵌数据
    let flatList = [1, 2, 3, ["司大屌", 4, 5, ["欧文", 5, 6]]];
    //flat 默认展开1层  可以输入参数 指定展开层数
    let nList = flatList.flat(2);
    console.log(nList); // [1, 2, 3, "司大屌", 4, 5, "欧文", 5, 6]


    //Array.from() 将字符串转换为数组
    let str = "我家住在黄土高坡";
    let strList = Array.from(str);
    //["我", "家", "住", "在", "黄", "土", "高", "坡"]
    console.log(strList);
    console.log(typeof strList); //object
    //数组 map函数使用

    let itemList = [
      {
        name: "vue",
        status: 1
      },
      {
        name: "java",
        status: 0
      },
      {
        name: "Spring",
        status: 1
      }
    ];

    //map函数可以处理数组特定对象
    let newItemList = itemList.map(function(item) {
      let obj = {};
      //浅复制
      Object.assign(obj, item);
      obj.status = obj.status ? "已开课" : "未开课";
      return obj;
    });

    console.log(itemList); //0: {name: "vue", status: 1} 1: {name: "java", status: 0} 2: {name: "Spring", status: 1}
    console.log(newItemList); //0: {name: "vue", status: "已开课"} 1: {name: "java", status: "未开课"} 2: {name: "Spring", status: "已开课"}

    //数组  reduce使用
    //array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
    /* total 必需初始值 initialValue若为空 total 为数组第一个元素    
       currentValue 必需当前元素   
       currentIndex 可选。当前元素的索引 
       arr 可选。当前元素所属的数组对象。 
       initialValue 可选。传递给函数的初始值
    */
    let str = "abdhsdancsaa";
    let strList = Array.from(str);

    let obj = strList.reduce(function(total, value) {
      total[value] ? total[value]++ : (total[value] = 1);
      return total;
    }, {});

    console.log(obj);

 

9、ES6 和ES8对象新特性和API

    //ES6和ES8对象新特性及新增方法

    //1.复制对象
    //注意:...复制对象是浅拷贝
    let obj = { name: "李某人", age: 23, hobby: { name: "hobby" } };
    let obj2 = { ...obj };
    obj.name = "司某人";
    obj.hobby.name = "篮球";
    console.log(obj == obj2); //false
    //注意 如果拷贝对象中存在对象,那么该字段将会存储的该对象的指针
    console.log(obj2); //{name: "李某人",age: 23,hobby: {name: "篮球"}}

    //2.设置默认值
    let sObj = { name: "李某人", age: 23 };
    let snObj = { ...sObj, name: "詹姆斯" };
    console.log(snObj); //{name: "詹姆斯", age: 23}

    //3.合并对象

    let sobj1 = { name: "欧文" };
    let sobj2 = { name: "科温顿", age: 23 };
    let sobj3 = { ...sobj1, ...sobj2 };
    let sobj4 = { ...sobj2, ...sobj1 };
    console.log(sobj3); //{name: "科温顿", age: 23}
    console.log(sobj4); //{name: "欧文", age: 23}

    //es5 书写对象 与 es6书写对象

    let name = "张三";
    let age = 23;

    let es5Obj = {
      name: name,
      age: age,
      sayHello: function() {
        console.log("es5--->Hello");
      }
    };
    //ES6更加直观
    let es6Obj = {
      name,
      age,
      sayHello() {
        console.log("es6--->Hello");
      }
    };

    es5Obj.sayHello();
    es6Obj.sayHello();

    //可计算的属性名
    let wName = "userName";
    //ES5写法
    let es5O = {};
    es5O[wName] = "王尼玛";
    //ES6初始对象写法
    let es6O = {
      [wName]: "司大雕"
    };

    console.log(es5O); //{userName: "王尼玛"}
    console.log(es6O); //{userName: "司大雕"}
    // Object.is  判断两个值相等
    console.log(Object.is(NaN, NaN)); //true
    console.log(NaN === NaN); //false
    console.log(+0 === -0); //true
    console.log(Object.is(+0, -0)); //false
    console.log({} === {}); //false
    console.log(Object.is({}, {})); //false

    //  Object.assign 拷贝对象 也是浅拷贝 与 ... 存在同样问题 拷贝对象中内嵌对象属性
    let obj = { name: "张三", age: 23 };
    let obj2 = {};
    //obj2 目标对象  obj 来源对象
    Object.assign(obj2, obj);
    console.log(Object.is(obj, obj2)); //false
    console.log(obj2); //{name: "张三", age: 23}

    //获取对象key  value  entrie
    //Object.keys() Object.values() Object.entries()
    let objK = { name: "王尼玛", age: 23, hobby: "睡觉" };

    console.log(Object.keys(objK)); // ["name", "age", "hobby"]
    console.log(Object.values(objK)); // ["王尼玛", 23, "睡觉"]
    console.log(Object.entries(objK)); //[Array(2), Array(2), Array(2)]

    //使用keys 循环复制对象
    let nObjK = {};
    for (let item of Object.keys(objK)) {
      nObjK[item] = objK[item];
    }

    console.log(nObjK); //{name: "王尼玛", age: 23, hobby: "睡觉"}

10、Map与WeakMap结构的特点

  JavaScript对象实质就是键值对的集合(Hash结构),但在对象里却只能用字符串作为
键名。在一些特殊的场景中满足不了业务需求,因此, Map这一数据对象提出。


Map对象:
  用于保存键值对,任何值。(对象或原始值都可以作为一个键名或一个值)

WeakMap:
   1、只接受引用对象作为键名。
   2、没有clear 没有size  无法遍历
 

    //Map对象使用

    //1
    let mapObj = new Map();
    mapObj.set([1, 2, 3], "科比");
    console.log(mapObj);

    //2new对象是初始化值
    //new Map([[key,value],[key,value],[key,value].....])
    let mapObj2 = new Map([
      ["name", "司大屌"],
      ["age", 23]
    ]);
    console.log(mapObj2);
    console.log(mapObj2.get("name")); //司大屌
    //has 检测是否存在key
    console.log(mapObj2.has("name")); //true
    //delete
    mapObj2.delete("name");
    console.log(mapObj2);

    //mapObj2.keys() mapObj2.values() mapObj2.entries()
    //默认遍历 mapObj2.entries()
    for (let item of mapObj2) {
      console.log(item);
    }

11、Set与WeakSet结构特点

Set是ES6提供的一种类似数组的数据结构,可以理解为集合。它和数组最大的区别就是:它的值不会重复。


WeakSet:
  1.数组成员必须是对象。
  2.无法遍历 不存在keys() values() entries() forEach()等方式和size属性
 
    let setObj = new Set();
    setObj.add(1).add(2);
    console.log(setObj);

    let setObj2 = new Set([1, 2, 3, 4, 5]);
    console.log(setObj2);

    setObj2.delete(2);
    console.log(setObj2);

    //setObj2.keys() setObj2.values()  setObj2.entries()
    //setObj2.keys() setObj2.values () 遍历的值相同
    //默认遍历的是  setObj2.values()
    for (let key of setObj2.keys()) {
      console.log(key);
    }

12、Map、Set与Array及Object区别

   // 判断对象中是否包含某个属性

    let obj = {
      name
    };
    obj["name"] = "李某人";
    //判断某个属性是否存在
    let checkIs = "name" in obj;
    let checkIs2 = "age" in obj;
    console.log("check", checkIs, checkIs2); //check true false
    //删除对象中某个属性
    delete obj.name;
    console.log(obj); //{}

    //类型转换

    //1 对象转换map
    let obj1 = {
      name: "李某人",
      age: 23
    };

    let map = new Map(Object.entries(obj1));
    console.log(map);

    //2 map转换对象
    let obj2 = Object.fromEntries(map);
    console.log(obj2);

    //3 数组转换set

    let array = [1, 2, 3, 4];
    let set = new Set(array);
    console.log(set);

    //4 set转换数组

    let arrsy2 = Array.from(set);
    console.log(arrsy2);

13、ES6中Proxy与Reflect

    //Proxy  ES6引入操作对象API 代理对象的读取 设置等操作

    let obj = {
      name: "李明明",
      age: 23,
      phone: "18700185678"
    };

    //第一个参数 用于代理的目标对象
    //第二个参数 一个对象,对代理对象进行拦截操作的函数
    let objProxy = new Proxy(obj, {
      //target 当前目标对象
      //key    目标对象属性名
      get: function(target, key) {
        switch (key) {
          case "phone":
            return target[key].substr(0, 3) + "****" + target[key].substr(7);
          default:
            return target[key];
        }
      },
      set: function(target, key, value) {
        switch (key) {
          case "name":
            return (target[key] = value + "代理名称");
          default:
            return target[key];
        }
      },
      // in操作
      has: function(target, key) {
        if (key in target) {
          console.log("属性存在");
        } else {
          console.log("属性不存在");
        }
      },

      //delete
      deleteProperty: function(target, key) {
        if (Object.is(key, "name")) {
          console.log("name属性无法删除");
        } else {
          delete target[key];
        }
      }
    });

    console.log(objProxy.phone); //187****5678
    objProxy.name = "司大屌";
    console.log(objProxy.name); //司大屌代理名称
    "name" in objProxy; //属性存在
    //delete objProxy["name"]; //name属性无法删除

    /**
     * Reflect
     *  ES6引入Reflect也是用来操作对象的,它将对象里一些明显属于语言
     *  内部方法移植到Reflect对象中,它对某些方法返回结果进行了修改,
     *  使其更合理,并且使用函数方法实现了Object命令式操作
     *
     * */

    let objR = {
      name: "李某人",
      age: 23
    };
    //以后操作对象尽量都使用Reflect对象
    //获取属性值
    console.log(Reflect.get(objR, "name")); //李某人
    //修改属性值
    Reflect.set(objR, "name", "詹姆斯");
    console.log(objR.name); //詹姆斯
    //检测属性名是否存在
    console.log(Reflect.has(objR, "name")); //true

14、ES6函数扩展

    //ES6函数扩展

    //1 函数默认参数
    function seyHello(x, y = "world") {
      console.log(x + y);
    }
    seyHello("hello"); //helloworld
    seyHello("你好", "世界"); //你好世界

    //2 可变参数
    function sumAdd(...v) {
      let num = 0;
      for (let p of v) {
        num += p;
      }
      console.log("num", num);
    }

    sumAdd(1, 2, 3, 4, 5);

15、箭头函数

   //箭头函数

    //声明函数
    const arrow = (x) => {
      console.log("我是箭头函数", x);
    };
    //调用
    arrow(100); //我是箭头函数 100

    //如果箭头函数参数只有一个可以省略() 如果返回只有一条语句可以省略{}

    const arrow2 = x => x * 2;
    console.log(arrow2(2)); //4
  

16、ES6类

    //ES5 使用构造函数来实现类的功能
    function Person(name, age) {
      this.name = name;
      this.age = age;
    }

    Person.prototype.sayHello = () => {
      console.log(`我叫${this.name},今年${age}`);
    };

    let p = new Person("张三", 23);
    console.log(p); //Person {name: "张三", age: 23}

    //ES6实现类的方法
    class PersonES6 {
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }

      sayHello() {
        console.log(`我叫${this.name},今年${this.age} 再也不给xx借钱`);
      }
    }

    let p1 = new PersonES6("李某人", 22);
    console.log(p1);
    p1.sayHello(); //我叫李某人,今年22 再也不给xx借钱

    //ES6类继承

    class A {
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }
    }

    class B extends A {}

    class C extends A {
      constructor(name, age) {
        //子类构造函数中super放到第一行
        super(name, age);
        this.name = name;
        this.age = age;
      }
      // get set 方法
      get getName() {
        return this.name;
      }

      set setName(value) {
        this.name = value;
      }

      //静态方法
      static sayHelloS() {
        console.log("我是静态方法");
      }
    }

    let cP = new C("李默", 22);
    console.log(cP); // {name: "李默", age: 22}
    console.log(cP.name); //李默
    console.log(cP.getName); //李默
    cP.setName = "张三";
    console.log(cP); // {name: "张三", age: 22}
    console.log(cP.name); //张三
    console.log(cP.getName); //张三
    //调用类的静态方法
    C.sayHelloS(); //我是静态方法

17、import export 

方式1

//JSFile1.js

export let a = 10;

export function sayHello() {
    console.log("hello");
}

//方式1
import { a, sayHello } from "../utils/jsFile1";
//引入全部 取个别名
import * as oneAll from "../utils/jsFile1";




方式2  推荐这种方式
//jsFile2

let a = 10;

function sayHello() {
    console.log("hello");
}

export default {
    a,
    sayHello
}


import two from "../utils/jsFile2";

console.log(two.a);
two.sayHello();

18、Promise

    //promise
    //1.主要用于异步计算
    //2.可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
    //3.可以在对象之间传递和操作promise,帮助我们处理队列

    //then()  调用的就是resolve()
    //catch() 调用的就是reject() 

    function ajax(num) {
      //resolve 成功时执行下一步操作
      //reject  失败时执行的下一步操作
      return new Promise((resolve, reject) => {
        if (Object.is(num, 200)) {
          resolve();
        } else {
          reject();
        }
      });
    }

    ajax(200)
      .then(() => {
        console.log("成功");
      })
      .catch(() => {
        console.log("失败");
      });

    //模拟多层异步回调使用

    function ajaxAsyn() {
      return new Promise((resolve, reject) => {
        setTimeout(() => resolve(), 1000);
      });
    }

    ajaxAsyn()
      .then(() => {
        console.log("任务进度1执行完成");
        return new Promise((resolve, reject) => {
          setTimeout(() => resolve(), 1000);
        });
      })
      .then(() => {
        console.log("任务进度2执行完成");
      });

19、iterator

   /**
     * iterator遍历器是一种接口,目的是为了给不同的数据结构提供统一的循环方式,
     * 任何数结构如果部署了iterator接口,就能够实现遍历的操作。
     *
     * 原生具有iterator接口
     *
     *  Array
     *  String
     *  Set
     *  Map
     *  函数的argument对象
     *
     * */

    let arrsy = [1, 2, 3, 4, 5];

    let iterator = arrsy[Symbol.iterator]();

    // 使用for of
    // for (const it of iterator) {
    //   console.log(it); // 1 2 3 4 5
    // }

    //使用 iterator.next() 迭代
    let s = iterator.next();
    while (!s.done) {
      console.log(s.value);
      s = iterator.next();
    }

20、async

async:
      async是异步简写,用于声明一个函数是异步函数.

awati:
     等待的是一个表达式,这个表达式的计算结果是Promise对象或者其他值.



 
    function fn1() {
      setTimeout(() => console.log("任务1"), 1000);
    }

    function fn2() {
      setTimeout(() => console.log("任务2"), 1000);
    }

    function fn3() {
      setTimeout(() => console.log("任务3"), 1000);
    }

    function init() {
      fn1();
      fn2();
      fn3();
    }

    /**
     * 任务1 任务2 任务3 在等待1秒后同时输出了
     * 若想实现 任务1 输出后 等待1秒输出任务2 任务2输出后等待1秒输出任务3
     * 使用async  结合 Promise
     *
     */
    init();
    


    //使用async Promise改进
    function pn1() {
      return new Promise(resolve => {
        setTimeout(() => {
          console.log("异步任务1");
          resolve();
        }, 1000);
      });
    }

    function pn2() {
      return new Promise(resolve => {
        setTimeout(() => {
          console.log("异步任务2");
          resolve();
        }, 1000);
      });
    }

    function pn3() {
      return new Promise(resolve => {
        setTimeout(() => {
          console.log("异步任务3");
          resolve();
        }, 1000);
      });
    }

    async function initP() {
      //await 会等待 Promise 中 resolve() 或 reject() 调用后执行
      //new Promise 中若没有调用.then() 或者.catch() 默认是传入的空函数,方法体中代码在返回对象时执行
      
      await pn1().then(() => {
        console.log("结束");
      });
      await pn2();
      await pn3();
    }

    initP();

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值