ES6基础语法

ECMAScript(ES6)基本语法介绍

1.新增数据类型——Symbol

  1. 介绍

    • Symbol类型的值通过Symbol函数生成,相同Symbol函数返回的值是唯一的。
    • Symbol函数可以接收字符串作为参数,但是即使相同参数返回的也是唯一值,即 Symbol('miaov') != Symbol('miaov')
  2. 实例

    打印结果:外部:undefined 、内部:男

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Symbol实例</title>
    </head>
    <body>
    <script>
      /*
      *Symbol一般用于属性保护,即属性私有化
      *属性私有化:即方法内部可以访问,但方法外部不可以访问
      */
      var Person = (function(){
        var _gender = Symbol('gender');
        function P(name,gender){
          this.name = name;
          this[_gender] = gender;
        }
        P.prototype.say= function() {
          console.log('内部'+this[_gender])
        }
        return P;
      })();
    
      var p1 = new Person('风雅', '男');
      console.log('外部'+p1[Symbol('_gender')]);
      console.log(p1.say());
    </script>
    </body>
    </html>
    

2.变量声明——const

块及作用域:由 {} 包含的代码块所产生的作用域

  1. Let

    • 不支持变量声明预解析(先声明后使用)

    • 支持块作用域

    • 不允许重复声明(暂存死区)

      点击按钮一:打印0

      点击按钮二:打印1

      点击按钮三:打印2

      即对应的索引值

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
        button.active {
          background: pink;
        }
    
        p {
          display: none;
        }
    
        p.active {
          display: block;
        }
      </style>
    </head>
    
    <body>
      <button class="active">按钮一</button>
      <button>按钮二</button>
      <button>按钮三</button>
      <p class="active">内容一</p>
      <p>内容二</p>
      <p>内容三</p>
    </body>
    <script>
      btns = document.querySelectorAll('button');
      ps = document.querySelectorAll('p');
      for (let i=0; i<btns.length; i++){
        btns[i].onclick=function(){
          console.log(i);
        }
      }
    </script>
    </html>
    

  2. var

    • 支持变量声明预解析

    • 不支持块作用域

    • 允许重复声明

      点击按钮一:打印3

      点击按钮二:打印3

      点击按钮三:打印3

      即打印循环结束时i的值

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
        button.active {
          background: pink;
        }
    
        p {
          display: none;
        }
    
        p.active {
          display: block;
        }
      </style>
    </head>
    
    <body>
      <button class="active">按钮一</button>
      <button>按钮二</button>
      <button>按钮三</button>
      <p class="active">内容一</p>
      <p>内容二</p>
      <p>内容三</p>
    </body>
    <script>
      btns = document.querySelectorAll('button');
      ps = document.querySelectorAll('p');
      for (var i=0; i<btns.length; i++){
        btns[i].onclick=function(){
          console.log(i);
        }
      }
    </script>
    </html>
    

  3. const——常量声明,一经声明不能改变

    • 不支持变量声明预解析(先声明后使用)
    • 支持块作用域
    • 不允许重复声明(暂存死区)

3.解构赋值

允许按照一定模式,从数组和对象中提取值,并对变量进行赋值,这被称为解构赋值

  1. 数组解构赋值

    顺序对应

    let [a, b, c] = [1, 2, 3];

  2. 对象解构赋值

    key 值对应

    let { foo, bar } = { foo: "aaa", bar: "bbb" }

  3. 解构赋值——别名

    foo: 原始名称

    f:别名

    let { foo: f, bar: b } = { foo: "aaa", bar: "bbb" }

  4. 多重解构

    let { foo: [a, b] } = { foo: [10,20], bar: "bbb" }

4.扩展运算符——...

把数组/对象转成参数序列(使用逗号分隔的序列)

['a,'b','c'] => 'a','b','c'相当于去除数组的中括号

{left:100, top:200} => left: 100, top: 200相当于去除大括号

  • 案例

    	// 合并数组
    	var arr1 = [1,7,3,6,2];
        var arr2 = ['a', 'b', 'c'];
        console.log( [...arr1, 'maiov', ...arr2] );  
    
    	// 合并对象
         let obj1 = {left:100, top: 200};
         let obj2 = {width: 200, height: 200};
    
         let obj3= {
           ...obj1,
           ...obj2
          };
    	  console.log(obj3);
    

5.迭代

  1. 迭代协议

    • 规定了迭代与实现的逻辑

    • 基本结构

          // 迭代协议
      	obj[Symbol.iterator] = function () {
            return {
              next: function () { // 迭代函数必须的
                return {
                  value: '' // 迭代输出值
                  done: true | faslse  // 是否结束迭代
                }
              }
            }
          }
      
  2. 迭代器

    • 具体的迭代实现逻辑,即 [Symbol.iterator]方法

      输出结果:left 100

      ​ top 200

    • 实例

      /*
          * 迭代对象
          *   实现了迭代器的对象
          *   迭代器:方法 [Symbol.iterator]
          */
      
          var obj = {
            left: 100,
            top: 200
          };
      
          // 迭代协议
          // 自定义迭代条件,以及返回值
          obj[Symbol.iterator] = function () {
            let keys = Object.keys(obj); // 获取对象的key值,返回一个数组
            let len = keys.length;
            let n = 0;
            return {
              next: function () { // 迭代函数必须的
                if (n < len) { // 迭代条件
                  return {
                    value: { k: keys[n], v: obj[keys[n++]] },// 迭代输出的值,此处的n++的含义是先输出obj[keys[n]]的值,然后在n++
                    done: false // false代表还需继续迭代
                  }
                } else {
                  return {
                    done: true
                  }
                }
              }
            }
          }
      
          // obj[Symbol.iterator]().next() => {done: true}
          for (var { k, v } of obj) { //of 是一个可迭代的对象
            console.log(k, v);
          }
      
  3. 迭代对象

    • 可被迭代的对象,含有 [Symbol.iterator]方法的对像
  4. 迭代语句

    • for…in:以原始插入的顺序迭代对象的可枚举属性

      输出结果:0, 1, 2

    • 实例

      <script>
          var arry = ['a', 'b', 'c'];
          for(var attr i arry){
            console.log(attr);
          }
       </script>
      
    • for…of:根据迭代对象的迭代器具体实现迭代对象数据

      输出结果:a, b, c

    • 实例

      <script>
          var arry = ['a', 'b', 'c'];
          for(var attr of arry){
            console.log(attr);
          }
       </script>
      

6.数据结构——Set

集合的基本概念:集合是由一组无序且唯一(即不能重复)的项组成。这个数据结构使用了与有限集合相同的数学概念,应用在计算机的数据结构中。

特点:key和value相同,没有重复的value。

  • ES6提供了数据结构Set。它类似于数组,但成员值唯一的,没有重复的值
  1. 如何创建一个Set

    const s= new Set([1, 2, 3]);
    console.log(s); 
    

  2. Set类的属性

    • size:类似于数组的length
  3. Set类的方法

    • set.add(value):添加一个数据,返回Set结构本身

      s.add('a'); //向数组添加a这一元素
      s.add('b').add('c').add('d'); //链式添加
      

    • set.delete(value):删除指定数据,返回一个布尔值,表示是否删除成功

      console.log(s.delete('a'));  //删除a,成功删除返回true,否则返回false
      

    • set.has(value):判断该值是否为Set的成员,返回一个布尔值

      console.log(s.has( 'a')); // 判断s中是否含有a这一元素,有则返回true,反之返回false
      
    • set.clear():清除所有数据,没有返回值

    • keys()返回键名的遍历器

    • values():返回键值的遍历器

    • entries():返回键值对的遍历器

    • foreach():使用回调函数遍历每个成员

7.数据结构——Map

字典:是用来存储不重复key的Hash结构。不同于集合(Set)的是,字典使用的是[键,值]的形式来存储数据的。

**Object对象 **:JavaScript 的对象(Object: {})只能用字符串当作键,这给他的使用带来很大的限制。

Map:为了解决这个问题,ES6提供了Map数据结构。他类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当做键。也就是说,Object结构提供了“字符串——值”的对应,Map结构提供了“值——值”的对应,是一种完善的Hash结构实现。如果你需要“键值对应的数据结构,Map比Object更加适合。

  1. 如何创建一个Map

    var map = new Map([
      ['a', 1],
      ['b', 2]
    ]);
    
  2. Map 类的属性

    • size:类似于数组的length
  3. Map 类的方法

    • map.set(key, value):设置键名key对应的键值为value,然后返回整个Map结构。如果key已经有值,则键值会被更新,否则就会生成新的键该键。

      map.set('fengya', 'shuai').set('new', 'fq');
      
    • map.get(key):get方法获取key对应的键值,如果找不到key,返回undefined。

    • map.delete(key):删除某个键,返回true,如果删除失败则返回false。

    • map.has(key):返回一个布尔值,表示某个键是否存在当前Map对象之中。

    • map.clear():清除所有数据,没有返回值。

    • map.keys():遍历所有的键名,并将其返回。

    • map.values():遍历所有的键值,并将其返回。

    • map.entries():遍历所有的键名与键值,并将其返回。

    • map.forEach():使用回调函数遍历每个成员。

  4. 使用注意事项:

    • map的键名跟内存地址绑定,只要内存地址不一样,则就代表不同的键名
    • map里面的key的排列顺序是按照添加顺序进行排列的。

8.Iteratorfor...of 循环

  1. 基本概念

    • 在ES6中新增加了Set和Map两种数据结构,再加上js之前原有的数组和对象,这样就有了四种数据集合,平时还可以组合使用它们,定义自己的数据结构,比如数组的成员是Map,Map的成员是对象等。这样就需要一种统一的接口机制,来处理所有不同的数据结构。
    • Iterator :这就是一种机制,它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署在Iterator 接口,就可以完成遍历操作,而且这种遍历操作是依次处理该数据结构的所有成员。
    • Iterator遍历器的作用:
      • 为各种数据结构,提供一个统一的、简便的访问接口。
      • 使得数据结构的成员能够按某种次序排列。
      • ES6新增了遍历命令for...of循环,Iterator接口主要提供for...of消费。
  2. 手写Iterator接口

    const arr = [1, 2, 3];
    function iterator(arr){
      let index = 0;
      return {
        next: function(){
          return index < arr.length ? {value: arr[index++], done: false} : {value: undefind, done: true};
        }
      }
    }
    const it = iterator(arr);
    console.log(it.next()); // 打印结果{value:1, done:false}
    console.log(it.next()); // 打印结果{value:2, done:false}
    console.log(it.next()); // 打印结果{value:3, done:false}
    console.log(it.next()); // 打印结果{value:undefind, done:true}
    
    • Iterator的遍历过程:
      • 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
      • 第一次调用指针对象的next()方法,可以将指针指向数据结构的第一个成员。
      • 第二次调用指针对象的next()方法,指针就指向数据结构的第二个成员。
      • 不断调用指针对象的next()方法,直到他指向数据结构的结束位置。
      • 每一次调用next()方法,都会返回数据结构的当前成员信息。具体来说,就是返回一个包含value和done两个属性的对象。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。
    • 凡是具有Symbol.iterator 属性的数据结构都具有 Iterator 接口
    • 凡是具有Symbol.iterator 属性的数据结构都可以进行解构赋值和使用扩展运算符...

9.class语法

  1. 基本概念:JS语言的传统方法是通过构造函数,定义并生成新的对象,是一种基于原型的面向对象系统。这种写法跟传统的面向对象语言(比如C++和Java)差异很大,很容易让新学这门语言的人感到困惑。所以在ES6中新增加了类的概念,可以使用class 关键字声明一个类,之后以这个类来实例化对象。

  2. 实例

    class Miaov {
      constructor(a, b){
        this.a = a;
        this.b = b;
        return this;
      }
      print(){
        console,log(this.a + ' ' + this.b );
      }
    };
    const miavo = new Miaov ('hello', 'world').print(); // 输出结果:hello world
    consoe.log(typeof Miaov); // 打印结果:function
    
    • Miaov 中的constructor方法是构造方法,this 关键字则代表实例对象。也就是说,ES6的构造函数,对应Miaov 这个类的构造方法。

    • Miaov 这个类除了构造方法,还定义了一个print 方法。注意,定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去就可以了。另外,方法直接不需要逗号分隔,加了会报错。

    • 构造函数的 prototype属性,在ES6的类上面继续存在。而且类的所有方法都定义在类的 prototype的属性上

      console.log(Miaov.prototype);
      
    • 定义在类中的方法都是不可以枚举的。

      console.log(Object.keys(Miaov.prototype));
      
    • constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor 方法,如果没有显示定义,一个空的 constructor 方法会被默认添加。

    • 生成类的实例对象的写法,与ES5完全一样,也是使用new命令。如果忘记加上new,像函数那样调用Class,将会报错。

  3. 继承

    • 案例

      <!DOCTYPE html>
      <html lang="en">
      
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
          canvas {
            box-shadow: 2px 2px 12px rgba(0, 0, 0, 0.5);
          }
        </style>
      </head>
      
      <body>
        <canvas id="canvas"></canvas>
        <!-- <script src="./bundle.js"></script> -->
        <script>
          window.onload = function () {
            const canvas = document.getElementById('canvas');
            const ctx = canvas.getContext('2d');
            const w = canvas.width = 600;
            const h = canvas.height = 400;
      
            class Ball {
              constructor(x, y, r) {
                this.x = x;
                this.y = y;
                this.r = r;
                this.color = `rgb(${~~Ball.rpFn([55, 255])}, ${~~Ball.rpFn([55, 255])}, ${~~Ball.rpFn([55, 255])})`;
                return this;
              }
              render(ctx) {
                ctx.save();
                ctx.translate(this.x, this.y);
                ctx.fillStyle = this.color;
                ctx.beginPath();
                ctx.arc(0, 0, this.r, 0, 2 * Math.PI);
                ctx.fill();
                ctx.restore();
                return this;
              }
              static rpFn(arr) {
                let max = Math.max(...arr), min = Math.min(...arr);
                return Math.random() * (max - min) + min;
              }
            }
      
            // const ball = new Ball(100, 100, 30).render(ctx);
      
            class SuperBall extends Ball {
              constructor(x, y, r) {
                super(x, y, r);
                this.vy = SuperBall.rpFn([2, 4]);
                this.g = SuperBall.rpFn([0.2, 0.4]);
                this.a = 0;
                return this;
              }
              move(ctx) {
                this.y += this.vy;
                this.vy += this.g;
      
                let current = this.vy * (-0.75);
      
                if (this.y + this.r >= ctx.canvas.height) {
                  this.y = ctx.canvas.height - this.r;
      
                  if (Math.abs(current - this.a) < 0.01) return false;
                  this.a = this.vy *= (-0.75);
                }
                ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
                super.render(ctx);
                return true;
              }
            }
      
            // const ball = new SuperBall(100, 100, 30).render(ctx);
      
            let ball, timer;
            canvas.onclick = function (e) {
              let x = e.offsetX, y = e.offsetY;
              let r = ~~Ball.rpFn([25, 55]);
              ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
              ball = new SuperBall(x, y, r).render(ctx);
      
              ballMove();
            }
      
            function ballMove() {
              timer = window.requestAnimationFrame(ballMove);
              if (!ball.move(ctx)) {
                window.cancelAnimationFrame(timer);
              }
            }
          }
        </script>
      </body>
      
      </html>
      
    • 说明

      • 子类继承父类 使用extends 关键字
      • 为父类指定静态方法,使用 static 方法名字
      • super
        • 在构造函数中可以当做一个函数来使用,相当于调用父类的构造函数。
        • 在原型方法中,可以当做一个对象来使用,相当于父类的原型对象,并且会自动绑定this到子类上。

10.Promise对象

  1. 基本概念

    • 是ES6中新增的异步编程解决方案,体现在代码中它是一个对象,可以通过Promise构造函数来实例化。
  • new Promise(cb) ===> 实例的基本使用 Pending Resolved Rejected
    • new Promise(cb)的状态
      • Pending(进行中) ===> Resolved(已完成)
      • Pending(进行中) ===> Rejected(已失败)
  1. 两个原型方法:

    • Promise.prototype.then()

    • Promise.prototype.catch()

    • 实例

      <!DOCTYPE html>
      <html lang="en">
      
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
      </head>
      
      <body>
        <script>
          /** 
          * 两个原型方法:
          *   - Promise.prototype.then() //捕获成功的回调
          *   - Promise.prototype.catch() //捕获失的回调
          */
          const imgs = [
            'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1074716685,4059509041&fm=27&gp=0.jpg',
            'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=4159865632,111097556&fm=27&gp=0.jpg',
            'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2551503021,1875446291&fm=27&gp=0.jpg'
          ];
          const p = new Promise(function (resolve, reject) { // resolve成功的回调函数, reject失败的回调函数
            const img = new Image();
            img.src = imgs[0];
            img.onload = function () {
              resolve(this);
            };
            img.onerror = function () {
              reject(new Error('图片加载失败'));
            }
          });
          // 加载完成之后会调用then 方法
          p.then(function (img) { // 成功回调
            document.body.appendChild(img);
            // },function(err){ // 失败回调,但不推荐使用
            //   console.log(err)
          }).catch(function (err) { // 失败回调,推荐使用
            console.log(err)
          })
        </script>
      </body>
      
      </html>
      
  2. 两个常用静态方法:

    • Promise.all():可以将多个Promise实例包装成一个新的Promise实例

      • 当所有的Promise实例的状态都变成resolved , Promise.all的状态才会变成resolved,此时返回值组成一个数组,传递给thenresolve函数

      • 只要其中一个被rejected,Promise.all的状态就会被rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数

      • 实例

         function loadImg(url) {
              const p = new Promise(function (resolve, reject) { // resolve成功的回调函数, reject失败的回调函数
                const img = new Image();
                img.src = url;
                img.onload = function () {
                  resolve(this);
                };
                img.onerror = function () {
                  reject(new Error('图片加载失败'));
                }
              });
              return p;
            }
            const allDone = Promise.all([loadImg(imgs[0]),loadImg(imgs[1]),loadImg(imgs[2])]);
            allDone.then(function(datas){
              datas.forEach(function(item, i){
                document.body.appendChild(item);
              })
            }).catch(function(err){
              console.log(err)
            })
        
    • Promise.resolve()

      • 第一种用法:参数是Promise实例,将不做任何修改,原封不动地返回这个实例

         function loadImg(url) {
              const p = new Promise(function (resolve, reject) { // resolve成功的回调函数, reject失败的回调函数
                const img = new Image();
                img.src = url;
                img.onload = function () {
                  resolve(this);
                };
                img.onerror = function () {
                  reject(new Error('图片加载失败'));
                }
              });
              return p;
            }
            // 参数是Promise实例,将不做任何修改,原封不动地返回这个实例
            Promise.resolve(loadImg(imgs[0])).then(function(img){
              document.body.appendChild(img);
            })
        
      • 第二种用法:将对象转化为Promise对象,然后立即执行thenable 对象的then方法

        Promise.resolve({
              then(resolve, reject){
                const img = new Image();
                img.src = imgs[1];
                img.onload = function(){
                  resolve(this);
                }
              }
            }).then(function(img){
              document.body.appendChild(img);
            })
        
      • 第三种用法:参数是一个基本数据类型或者不传参数,那么返回一个状态为resolved的Promise对象

        	// 传递一个基本数据类型
        	Promise.resolve('fengya').then(function(str){
               console.log(str); // fengya
             })
        	// 不传参数
            const p =Promise.resolve();
            console.log(p); // Promise {<resolved>: undefined}
        

11.Generator函数

  1. 基本概念 :在形式上,Generator是一个普通函数,但是有两个特征。

    • function命令与函数之间有一个星号。

    • 函数体内部使用yield语句,定义遍历器的每个成员,即不同的内部状态。

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
      </head>
      <body>
        <script>
          /**
          * 基本概念 :在形式上,Generator是一个普通函数,但是有两个特征。
          *   - function命令与函数之间有一个星号。
          *   - 函数体内部使用yield语句,定义遍历器的每个成员,即不同的内部状态。
          */
      	/**
          * 输出结果:先输出 1,然后输出 {value: undefined, done: false}, 1秒过后输出3
          */
          function* fn(){
            console.log(1);
            // yield console.log(2);
            let val = yield getData(); // 接收传递出来的数据
            console.log(val);
            console.log(3)
          }
      
         function getData(){
            setInterval(function(){
              // 此处可以调用ajax获取数据,然后将数据通过next参数传递出去,例如此处传递100
              f.next(100);
            },1000)
          }
          let f = fn();
      	// 调用函数
      	f.next();
        </script>
      </body>
      </html>
        
      
    • 封装自动调用函数co

      <!DOCTYPE html>
      <html lang="en">
      
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
      </head>
      
      <body>
        <script>
          function* fn() {
            console.log(1);
            let val = yield getData(); // 接收传递出来的数据
            console.log(val);
            console.log(3)
          }
      
          function getData() {
            // 将其包装为Promise对象
            return new Promise((resolve, reject) => {
              setTimeout(function () {
                resolve(100);
              }, 1000);
            });
          }
          
          function co(callback){
            let cb = callback();
            // 封装一个next方法调用f
             // 用co 递归调用cb的next方法从而实现自动调用f.next
            function next(d){
              let result = cb.next(d); // 返回结果{value,done}
              if(result.done){
                return; // 所有的f.next() 执行结束了
              }
              // 获取数据,并传递出去
              result.value.then(data => {
                next(data); // 递归调用next()方法
              })
            }
            next();
          }
          co(fn);
        </script>
      </body>
      
      </html>
      
  2. async 方式

    • 实例

      <!DOCTYPE html>
      <html lang="en">
      
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
      </head>
      
      <body>
        <script>
          async function fn() {
            console.log(1);
            
      
            try{ //成功捕获
              let v = await getData();
              console.log(v);
            } catch(e){ // 失败捕获
              console.log(e)
            };
            // console.log(v);
            // console.log(3)
          }
      
          function getData() {
            // 将其包装为Promise对象
            return new Promise((resolve, reject) => {
              setTimeout(function () {
                resolve(100); // 成功返回100
                reject('err');  // 错误返回err
              }, 1000);
            });
          }
          
          fn();
      
        </script>
      </body>
      
      </html>
      

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值