四.ES6基础知识二(超详细!!!)

这篇博客深入讲解了ES6中的重要特性,包括函数的形参默认值、解构、rest参数和箭头函数。接着介绍了迭代器Iterator的作用、访问方式以及原生具备Iterator接口的数据类型。此外,还详细阐述了Set和Map集合的特性和API。在类(class)部分,解释了构造器、实例属性和方法、静态属性与方法、继承等概念。探讨了Symbol的用途和内置值,以及Promise的创建、实例方法和静态方法。最后,介绍了Generator和async关键字在异步编程中的应用。
摘要由CSDN通过智能技术生成

9.函数

ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。通常情况下,定义了默认值的参数,应该是函数的尾参数

函数的length属性,将返回没有指定默认值的参数个数

如果设置的默认值不是函数的尾参数,那么length只计算默认值前面的参数的长度

参数默认值可以与解构赋值的默认值,结合起来使用。

1)形参默认值

let myFun1 = function(a,b,c = 10){
  console.log(a,b,c);
  console.log(arguments);     //ES5中,实参列表,类数组对象
}
myFun1(null,2);
//null 2 10
// [Arguments] { '0': null, '1': 2 }

let myFun = function(x,y=123,z){
  console.log(x,y,z);
}
myFun();
console.log(myFun.length);     //1

2)解构

//2. 对象解构
let myFun2 = function({a,b,c}){
  console.log(a,b,c);
}
myFun2({c:'wll',a:1,b:2});    //1 2 wll

//3. 数组解构
let myFun3 = function([a,b,c]){
  console.log(a,b,c);
}
myFun3([1,2,3]);    //1 2 3

3)rest参数

//4. ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。
// ...用在函数的形参位置,叫做rest参数,也叫拓展运算符的逆运算
let myFun4 = function (a,...b){
  console.log(a,b);
}
myFun4(1,2,3,4,5,6)   //1 [ 2, 3, 4, 5, 6 ]

4)箭头函数

this指向

普通函数:this指向调用者,没有调用者指向global

箭头函数:没有自己的this,this指向'声明时'外部作用域的this

// 箭头函数,指向声明时外部作用域的this
let arrowFun = ()=>{
  console.log(this);    //{}全局
}
let obj = {
  name:'wll',
  age:18,
  gender:'female',
  sayName:()=>{
    console.log(this);    //指向全局
  },
  sayAge(){
    return ()=>{
      console.log(this);      //指向obj
    }
  },
  sayGender(){
    return arrowFun;    //指向全局
  }
}
obj.sayName();
obj.sayAge()();
obj.sayGender()();
arrowFun();

this.name = 'cjk';
module.exports.gender = 'male';

// 默认情况下,全局this和module.exports一样
console.log('全局this',this);   //全局this { name: 'cjk', gender: 'male' }
console.log('module默认导出',module.exports);   //module默认导出 { name: 'cjk', gender: 'male' }
console.log(this === module.exports);   //true

箭头函数写法

// 箭头函数的极简形式    只有一个形参,有且只有一条返回语句
//形参只有一个时,可省略括号,只有一句返回语句时,箭头后面可直接写表达式
let result = arr.filter(item => item > 5)

// ES6箭头函数完整写法
let result = arr.filter((item) => {
  retrun item > 5
})

// ES5写法
let result = arr.filter(function(item) {
  retrun item > 5
})

10.迭代器Iterator

实现了iterator接口的数据,即是可迭代的数据

1)作用

1)为实现iterator接口的数据,提供统一的访问机制(for of循环) 2)数据内部成员按照一定的次序排列,通过调用.next()方法,使指针向下移动,指向下一个成员 3)供ES6中的for of 循环来调用

2)访问

iterator.next() 通过调用.next方法,可以使迭代器对象中的指针向下移一位 value有值,done就为false value为undefined时,done为true

let arr1 = ['tom','vicky','gicky'];
let values = arr1.values();
//console.log(typeof(values.next()));   //object
console.log(values.next()); //values.next()打印出来是个对象
//{ value: 'tom', done: false }
console.log(values.next()); 
//{ value: 'vicky', done: false }
console.log(values.next()); 
//{ value: 'gicky', done: false }
console.log(values.next()); 
{ value: undefined, done: true }

3)for of 使用

可以遍历实现了iterator接口的数据

// for of
let arr1 = ['tom','vicky','gicky'];
let values = arr1.values();
for(let value of values){
  console.log(value);
}
//tom  vicky  gicky

4)for of 实现(.next())

let arr1 = ['tom','vicky','gicky'];
let values = arr1.values();
let item ;
while(!(item = values.next()).done){
  console.log(item.value);
}
//tom  vicky  gicky

5)原生具备 Iterator 接口的数据

Array、Map、Set、String、arguments、NodeList 等

Symbol.iterator(iterator接口)指向数据的默认迭代器生成方法

let iterator1 = [1,2,3][Symbol.iterator]()
console.log(iterator1);    //Object [Array Iterator] {}
let iterator = 'hello'[Symbol.iterator]()
console.log(iterator);      //Object [String Iterator] {}
console.log(iterator.next());   //{ value: 'h', done: false }
console.log(iterator.next());   //{ value: 'e', done: false }
console.log(iterator.next());   //{ value: 'l', done: false }
console.log(iterator.next());   //{ value: 'l', done: false }
console.log(iterator.next());     //{ value: 'o', done: false }
console.log(iterator.next());     //{ value: undefined, done: true }
// [Symbol.iterator] 接口存在在原型对象上
String.prototype[Symbol.iterator]==='hello'[Symbol.iterator]()  // true

11.Set集合

类似于数组,key和value是相同

1)特性

不允许重复值出现

应用:数组去重

Array.form(new Set(arr))

2)API

Set.prototype.size 返回Set实例的成员总数。

Set.prototype.add(value) 添加某个值,返回Set结构本身

Set.prototype.delete(value) 删除某个值,返回一个布尔值,表示删除是否成功。

Set.prototype.has(value) 返回一个布尔值,表示该值是否为Set的成员。

Set.prototype.clear() 清除所有成员,没有返回值。

Set.prototype.keys() 返回键名的遍历器

Set.prototype.values() 返回键值的遍历器

Set.prototype.entries() 返回键值对的遍历器

Set.prototype.forEach() 使用回调函数遍历每个成员

let arr = [1,2,3,4,4,5,3,2,1,7];
let set = new Set(arr);
//1. 返回Set实例的成员总数。
console.log(set.size);    //6
//2. 添加某个值,返回Set结构本身
console.log(set.add(100));    //Set(7) { 1, 2, 3, 4, 5, 7, 100 }
//3. 删除某个值,返回一个布尔值,表示删除是否成功。
console.log(set.delete(1));   //true
//4. 返回一个布尔值,表示该值是否为Set的成员。
console.log(set.has(1));    //false
//5. 清除所有成员,没有返回值。
// console.log(set.clear());
//6. 返回键名的遍历器
//返回键值的遍历器
//返回键值对的遍历器
console.log(set.keys());    //[Set Iterator] { 2, 3, 4, 5, 7, 100 }
console.log(set.values());    //[Set Iterator] { 2, 3, 4, 5, 7, 100 }
console.log(set.entries());   //[Set Entries]   {[ 2, 2 ],[ 3, 3 ],[ 4, 4 ],[ 5, 5 ],[ 7, 7 ],[ 100, 100 ]}
// 7.使用回调函数遍历每个成员
set.forEach((value)=>{
  console.log(value);       //2, 3, 4, 5, 7, 100
});
// console.log(set);   //Set(6) { 2, 3, 4, 5, 7, 100 }

12.Map集合

类似于对象,key-value对应的集合。

1)特点

key值不局限于字符串,可以是任意数据类型

2)API

Map.prototype.size 返回 Map 结构的成员总数。

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

Map.prototype.get(key) get方法读取key对应的键值,如果找不到key,返回undefined。 Map.prototype.has(key) has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。 Map.prototype.delete(key)delete方法删除某个键,返回true。如果删除失败,返回false。 Map.prototype.clear() 清除所有成员,没有返回值

Map.prototype.keys() 返回键名的遍历器

Map.prototype.values() 返回键值的遍历器

Map.prototype.entries() 返回键值对的遍历器

Map.prototype.forEach() 使用回调函数遍历每个成员

let obj1 = {
  name:'tom',
  age:12,
  gender:'male'
}
let map = new Map(Object.entries(obj1));
// 1.  .set(key, value)   set方法设置键名key对应的键值为value,然后返回整个map结构。如果key已经有值,则键值会被更新,否则就新生成该键。
map.set(true,0);
map.set({a:1,b:2},['tom','terry'])
// 2.  .size               返回 Map 结构的成员总数。
console.log(map.size);      //5
console.log(map);           //Map(5){...}
// 3.get方法读取key对应的键值,如果找不到key,返回undefined。
console.log(map.get(true));;    //0
// 4.使用回调函数遍历每个成员
map.forEach((value,key)=>{
  console.log(value,key);   //tom name....
})

13.class类

1)介绍

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。 通过class关键字,可以定义类。ES6 的class可以看作是构造函数一个语法糖 语法糖:具有特殊功能的代码写法,内部封装了一些方法,让一些复杂代码的编写及其用法变得简单

2)构造器

constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。 一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。

3)实例属性、方法

定义在类体中的方法称为实例方法。如下,sayName方法就是实例方法, 本质上该方法应该是声明在Person.prototype中,可供所有的实例调用,因此称为实例方法。

class Person {
  // 静态属性 使用static关键字来修饰
  static weight = '50kg'
  // 实例属性 构造器,里面声明实例属性  维护实例的私有属性
  constructor(name,age,gender){
    // 实例的私有属性
    this.name = name ; 
    this.age = age ;
    this.gender = gender ;
  }
  // 实例私有属性
  test=['hello']
  // 实例方法,不需要任何关键字来修饰
  // 其实是存放在类构造器函数的原型对象的方法中
  // 公有方法
  sayName(){
    console.log('my name is:',this.name);
  }
  // 静态方法 使用static关键字来修饰
  static sayWweight(){
    console.log(this.weight);
  }
}
// 实例化
let p = new Person('tom',20,'男');

console.log(p);   //Person { test: [ 'hello' ], name: 'tom', age: 20, gender: '男' }
p.sayName();      //my name is: tom

// 通过class类来调用静态属性和方法
console.log(Person.weight);   //50kg
Person.sayWweight();          //50kg

4)静态属性、方法

通过static关键字来定义静态属性和静态方法。 

静态属性和静态方法是定义在类【构造函数】上的,所以可以通过类【构造函数】直接访问。

在静态方法中,this指向当前类【构造函数】

5)继承

ES5继承

借用构造函数继承

function Animal() {

}

function Dog() {

        Animal.call(this)

}

原型链继承

子构造函数的原型指向父构造函数的实例

Dog.prototype = new Anmimal()

Dog.prototype = Anmimal.prototype

ES6继承

用法

class Dog extends Anmimal {

        constructor(name,age,weight) {

                super(name,age);

        }

}

let dog = new Dog('二狗',1,'10KG')

子类继承父类(构造函数继承,继承静态方法、属性)

子类的构造函数继承父类的构造函数

子类构造函数的原型对象指向父类构造函数

Dog.proto === Animal

子类原型对象继承父类原型对象(方法继承,继承实例方法、属性)

Dog.prototype.proto === Animal.prototype

dog.proto.proto === Animal.prototype

class Animal{
  static animalAttr = 'Animal静态属性';
  constructor(name,age){
    this.name = name;
    this.age = age;
  }
  animalFun(){
    console.log('Animal实例方法');
  }
  static animalStaFun(){
    console.log('Animal静态方法');
  }
}
class Dog extends Animal{
  constructor(name,age,color,weight){
    super(name,age);
    this.color = color;
    this.weight = weight;
  }
}
// 继承了Animal类的实例属性和实例方法
//子类的原型对象继承父类的原型对象
let dog = new Dog('dog',6,'white','10kg');
console.log(dog);   //Dog { name: 'dog', age: 6, color: 'white', weight: '10kg' }
dog.animalFun();    //Animal实例方法

// 继承了Animal类的静态属性和静态方法
// 子类的对象指向父类的对象
console.log(Dog.animalAttr);    //Animal静态属性
Dog.animalStaFun();           //Animal静态方法

// 原型链继承   实例属性和实例方法
console.log(Dog.prototype.__proto__ === Animal.prototype);    //true
console.log(dog.__proto__.__proto__ === Animal.prototype);    //true

// 构造函数继承  静态属性和静态方法
console.log(Dog.__proto__===Animal);    //true

6)实例

class Message {
  constructor(status,message,data){
    this.status = status;
    this.message = message;
    this.data = data;
    this.timestamp =new Date().getTime();
  }
}
module.exports = Message;
let Message = require('./3.response class')
let message = new  Message(200,'操作成功','null');
console.log(message);

14.Symbol

1)介绍

ES6 引入的一种新的原始数据类型Symbol,表示独一无二的值。 Symbol函数可以接受参数,表示对于这个唯一值的描述。

2)使用

1.Symbol()函数会返回symbol类型(基本数据类型)的值

symbol类型的值是独一无二的

2.在对象中使用symbol,用于对象的属性名,就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖

// type of 返回的值有:number string boolean undefined symbol      object function
// ES6 引入的一种新的原始数据类型Symbol,表示独一无二的值。
// Symbol函数可以接受参数,表示对于这个唯一值的描述。
let sy1 = Symbol('sy1');
let sy2 = Symbol('sy2');
console.log(sy1);   //Symbol(sy1)
console.log(sy2);   //Symbol(sy2)
console.log(sy1 == sy2);    //false
console.log(typeof sy1);    //symbol基本数据类型

// 由于每一个 Symbol 值都是不相等的,这意味着 Symbol 值可以作为标识符
// 用于对象的属性名,就能保证不会出现同名的属性。
// 这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖
let obj1 = {
  name:'tom',
  age:12,
  gender:'male',
  [sy1]:'terry'   //key为变量时,需要用[]包裹
}
console.log(obj1);    //{ name: 'tom', age: 12, gender: 'male', [Symbol(sy1)]: 'terry' }
console.log(obj1[sy1]);   //terry

3)Symbol.for(key)

和 Symbol()不同的是,用Symbol.for()方法创建的symbol会被放入一个全局symbol注册表中。

并不是每次都会创建一个新的symbol,它会首先检查给定的 key 是否已经在注册表中了。

假如是,则会直接返回上次存储的那个。否则,它会再新建一个。

比如:调用Symbol.for("cat")30 次,每次都会返回同一个 Symbol 值,但是调用Symbol("cat")30 次,会返回 30 个不同的 Symbol 值。

如果想要用同一个变量,可以使用Symbol.for('name')注册一个全局的,下次如果要获取该symbol值,则再次Symbol.for('name')

let sy1 = Symbol('one');
let sy2 = Symbol('one');    
console.log(sy1,sy2);     //Symbol(one) Symbol(one)
console.log(sy1===sy2);   //false

// Symbol.for()通过该方法可以获取之前的唯一值它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。
// 如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局。
// key-->symbol
let sy3 = Symbol.for('two');
let sy4 = Symbol.for('two');
console.log(sy3,sy4);     //Symbol(two) Symbol(two)
console.log(sy3===sy4);   //true

4)Symbol.keyFor(sy1)

检测symbol值是否在全局登记过,返回key或者undefined。 返回一个已登记的 Symbol 类型值的 key ,用来检测该字符串参数作为名称的 Symbol 值是否已被登记。

let sy1 = Symbol('one');
let sy2 = Symbol('one'); 
let sy3 = Symbol.for('two');
let sy4 = Symbol.for('two');
// Symbol.keyFor()  方法返回一个已登记的 Symbol 类型值的key。 
// symbol-->key
console.log(Symbol.keyFor(sy1));    //undefined
console.log(Symbol.keyFor(sy2));    //undefined
console.log(Symbol.keyFor(sy3));    //two
console.log(Symbol.keyFor(sy4));    //two

// Symbol.for()       // key-->symbol
// Symbol.keyFor()   // symbol-->key
let key = Symbol.keyFor(sy3);
let value = Symbol.for(key);
console.log(value === sy3);         //true

5)应用:消除魔术字符串

魔术字符串指的是,在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。 风格良好的代码,应该尽量消除魔术字符串,改由含义清晰的变量代替。

// 消除魔术字符串
let shapes = {
  SJX:Symbol('三角形'),
  JX:Symbol('矩形'),
  YX:Symbol('圆形')
}
function computedArea (shape,options){
  let result = 0;
  switch (shape){
    case shapes.SJX:
      result = .5*options.width*options.height;
      break;
    case shapes.JX:
      result = options.width*options.height;
      break;
    case shapes.YX:
      result = Math.PI*options.r*options.r;
      break;
    default:
      result = -1;
      break;
  }
  return result;
}
let result = computedArea(shapes.SJX,{width:10,height:20});
console.log(result);

6)内置Symbol值

Symbol.iterator(iterator接口)指向数据的默认迭代器生成方法

let iterator1 = [1,2,3][Symbol.iterator]()
console.log(iterator1);    //Object [Array Iterator] {}
let iterator = 'hello'[Symbol.iterator]()
console.log(iterator);      //Object [String Iterator] {}
console.log(iterator.next());   //{ value: 'h', done: false }
console.log(iterator.next());   //{ value: 'e', done: false }
console.log(iterator.next());   //{ value: 'l', done: false }
console.log(iterator.next());   //{ value: 'l', done: false }
console.log(iterator.next());     //{ value: 'o', done: false }
console.log(iterator.next());     //{ value: undefined, done: true }
// [Symbol.iterator] 接口存在在原型对象上
String.prototype[Symbol.iterator]==='hello'[Symbol.iterator]()  // true

15.Promise

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

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。

Promise对象,可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。 Promise对象提供统一的接口,使得控制异步操作更加容易。

1)创建Promise实例

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject,它们是两个函数

Promise对象代表一个异步操作有三种状态: pending(进行中)、fulfilled(已成功)和rejected(已失败)。

状态发生改变之后就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)

const promise = new Promise(function(resolve,reject){
  if(1<0){
    const response = {
      status:200,
      message:'操作成功',
      data:null,
      timestamp:new Date().getTime()
    }
    resolve(response);   //promise内部状态pending -> fulfilled
  }else{
    const response = {
      status:500,
      message:'后台接口异常',
      data:null,
      timestamp:new Date().getTime()
    }
    reject(response);   //promise内部状态 pending -> rejected
  }
})
// promise实例直接调用.then().catch(),这种方法叫链式调用
//then()    内部成功调用then()内部的回调
//catch()   失败调用catch()内部的回调捕获异常
promise.then((res)=>{
  console.log(res);
}).catch((err)=>{
  console.log(err);
});

2)实例方法

这三个方法的返回值都是promise的实例,可以使用链式调用

.then()
  // promise状态为fulfilled
  参数:函数,函数内部的参数是resolve传过来的实参
.catch()
  // promise状态为rejected 
  参数:函数,函数内部的参数是reject传过来的实参
.finally()
  无论promise状态是成功还是失败,都会执行里面的代码

通过promise实例方法,访问内部的状态

<script>
    window.onload=function(){
      const baseUrl = 'http://47.94.46.113:8888';
      function getPromise(url,method){
        return new Promise(function(resolve,reject){
          $.ajax({
            url:baseUrl+url,
            method,
            success(res){
              resolve(res);
            },
            error(err){
              reject(err);
            }
          })
        })
      }
      
      // 通过工厂函数获取promise实例
      let promise1 = getPromise('/index/category/findAll','get');
      let promise2 = getPromise('/index/carousel/findAll','get');
      // 通过promise实例方法,访问内部的状态
      promise1.then(res=>{
        console.log(res);
      }).catch(err=>{
        console.log(err);
      // .finally()无论成功或者失败都会调用
      }).finally(()=>{
        console.log('finally');
      })

      promise2.then(res=>{
        console.log(res);
      }).catch(err=>{
        console.log(err);
      })
    }
</script>

3)静态方法

1.Promise.all([pro1,pro2])

将pro1和pro2包装成数组作为实参传递进去 返回值:promise对象。结果 =》pro1,pro2都成功才成功,有一个失败就失败

    window.onload=function(){
      const baseUrl = 'http://47.94.46.113:8888';
      function getPromise(url,method){
        return new Promise(function(resolve,reject){
          $.ajax({
            url:baseUrl+url,
            method,
            success(res){
              resolve(res);
            },
            error(err){
              reject(err);
            }
          })
        })
      }
      // 通过工厂函数获取promise实例
      let promise1 = getPromise('/index/category/findAll','get');
      let promise2 = getPromise('/index/carousel/findAll','get');

      // Promise.all([p1,p2])
      // 返回值:Promise实例,当p1,p2状态都为fulfilled时候,该实例的状态才为fulfilled,此时p1,p2的返回值组成一个数组,传递给该实例的回调函数;
      // 只要p1,p2的返回值有一个变为rejected,该实例状态为rejected
      let promise3 = Promise.all([promise1,promise2])
      promise3.then(res=>{
        console.log(res);
      }).catch(err=>{
        console.log(err);
      })

2.Promise.race([pro1,pro2])

将pro1和pro2包装成数组作为实参传递进去 返回值:promise对象。结果 =》pro1,pro2谁先回来就用谁都结果(无论成功或者失败)

     // Promise.race([p1,p2])
      // 返回值:Promise实例,当p1,p2之中有一个实例率先改变状态,该实例的状态就跟着改变。
      // 那个率先改变的 Promise 实例的返回值,就传递给该实例的回调函数。
      let promise4 = Promise.race([promise1,promise2])
      promise4.then(res=>{
        console.log(res);
      }).catch(err=>{
        console.log(err);
      })

3.Promise.any([pro1,pro2])

将pro1和pro2包装成数组作为实参传递进去 返回值:promise对象。结果 =》pro1,pro2都失败才失败,有一个成功就成功

      // Promise.any([p1,p2])
      // 返回值:Promise实例,只要p1,p2状态有一个变为fulfilled,该实例的状态为fulfilled;
      // p1,p2状态都变为rejected,该实例状态才为rejected
      let promise5 = Promise.any([promise1,promise2])
      promise5.then(res=>{
        console.log(res);
      }).catch(err=>{
        console.log(err);
      })

4.Promise.resolve()

参数:任意

返回值:状态为fulfilled的promise对象

      // Promise.resolve()
      // 用于将现有对象转化为Promise成功的实例
      // 参数:任意值
      let obj1 = {
        name:'tom',
        age:18,
        gender:'男'
      }
      console.log(Promise.resolve(obj1));
      let promise6 = Promise.resolve(obj1);
      promise6.then((res)=>{
        console.log(res);
      })

5.Promise.reject()

参数:任意

返回值:状态为rejected的promise对象

       // Promise.reject()
      // 返回一个新的 Promise 实例,该实例的状态为rejected
      // 参数:错误信息
      let obj2 = {
        status:500,
        message:'操作失败',
        data:null,
        timestamp:new Date().getTime()
      }
      let promise7 = Promise.reject(obj2)
      promise7.catch((err)=>{
        console.log(err);
      })

4)promise.ajax

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./jQuery.js"></script>
  <script>
    window.onload = function(){
      const baseUrl = 'http://47.94.46.113:8888'
      const promise = new Promise(function(resolve,reject){
        $.ajax({
          url:baseUrl+'/index/category/findAll',
          method:'get',
          // 异步请求成功,调用reserve
          success(res){
            resolve(res)
          },
          // 异步请求失败,调用reject
          error(res){
            reject(res)
          }
        })
      })
      promise.then((res)=>{
        console.log(res);
      }).catch((err)=>{
        console.log(err);
      })
    }
  </script>
</head>
<body>
  
</body>
</html>

16.Generator

是ES6的异步编程解决方案

类似于状态机,内部封装了多个状态

返回值:迭代器对象

通过调用.next()方法,访问迭代器对象内部的状态

1)特点

Generator函数有两个特征:

1.function关键字与函数名之间有个星号;

2.函数内部使用yield表达式

2)使用

总结Generator函数

异步编程解决方案 异步代码 同步编写

function* genFun() {

         let result = yield 'one'

        console.log(result); // hello是下方next的参数 yield 'two'

        retrun 'others'

}

let gen = genFun(); // gen是generator函数返回的迭代器对象

gen.next();

gen.next('hello')         //拿到的不是yield后面的状态描述

// 声明一个Generator函数
function* myGenFun(){
  console.log('状态一');
  let result = yield 'hello'    //result出口数据,result和hello没有关系

  console.log('状态二');
  console.log(result);        //result接口数据,result和第二次调用.next()方法传递的参数有关系
  yield 'world'

  console.log('状态三');
  return 'ending'   //return标志着该函数的结束
}
// generator函数的执行结果,是一个迭代器对象
let result = myGenFun()
console.log(result);    //Object [Generator] {}
console.log(result.next());   //状态一  { value: 'hello', done: false }
console.log(result.next('你好')); //状态二  你好  { value: 'world', done: false }
console.log(result.next());   //状态三    { value: 'ending', done: true }

3)generator ajax

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./jQuery.js"></script>
  <script>
    const baseUrl = 'http://47.94.46.113:8888';
    function getAjax(){
      return $.ajax({
        url:baseUrl+'/index/category/findAll',
        method:'get',
        success(res){
          iterator.next(res)
        }
      })
    }
    // 第一个状态的出口数据,作为下一个状态的入口数据
    // 这个数据是第二次调用.next()传递的实参
    function* myGenFun(){
      // 获取数据
      let result = yield getAjax()

      // 处理数据
      console.log('处理数据:',result);
      yield '结束'
    }
    
    let iterator = myGenFun();
    // 手动启动该迭代器的方法
    iterator.next();

  </script>
</head>
<body>
  
</body>
</html>

17.async

async函数是generator函数的语法糖,是ES6的异步编程解决方案

1)关键字

function关键字前加上 async(异步) 异步请求之前,加上 await(等待)

2)使用

async function findAll() {

        let result = await $.get('......');

        console.log(result.data)

}

  <script src="./jQuery.js"></script>
  <script>
    window.onload = function(){
      const baseUrl = 'http://47.94.46.113:8888';
      async function findAllCategory(){
        let res = await $.ajax({
          url:baseUrl+'/index/category/findAll',
          method:'get'
        })
        console.log(res);
          // let res = await axios.get({
          //   url:baseUrl+'/index/category/findAll',
          //   method:'get'
          // })
          // return res
      }
      findAllCategory();
      // findAllCategory().then(res=>{
      //   console.log(res);
      // })
    }
  </script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值