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>