Iterator遍历器:
// 一种数据结构只要部署了 Iterator 接口,我们就称这种数据结构是“可遍历的”,
// ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,
// 一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”
// 原生具备 Iterator 接口的数据结构如下:
// Array
// Map
// Set
// String
// TypedArray
// 函数的 arguments 对象
// NodeList 对象
var m = new Map();
m.set("name","zs");
m.set("age",100);
for(let item of m){
console.log(item);//[key,value];
}
// 任意一个对象的Symbol.iterator属性等于该对象的遍历器生成函数,调用该函数返回遍历器对象(指针)
var result=m[Symbol.iterator]();
console.log(result); //MapIterator {"name" => "zs", "age" => 100}
console.log(result.next()); //{value: Array(2), done: false}
console.log(result.next()); //{value: Array(2), done: false}
console.log(result.next()); //{value: undefined, done: true}
// 注意:对于遍历器对象来说,done: false和value: undefined属性都是可以省略的
Generator函数:
// Generator 函数是一个状态机,封装了多个内部状态。
// 执行 Generator 函数会返回一个遍历器指针对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。
// 调用 Generator 函数,返回一个遍历器对象,代表 Generator 函数的内部指针。以后,每次调用遍历器对象的next方法,
// 就会返回一个有着value和done两个属性的对象。value属性表示当前的内部状态的值,是yield表达式后面那个表达式的值;
// done属性是一个布尔值,表示是否遍历结束。
function* fn() {
console.log(1);
var y1 = yield "y1"; // y1的值是next()方法的传递的实参,每个next()的实参是传给上一个yield变量
console.log(y1); // 2
var y2 = yield "y2";
console.log(y2); // 3
return "y3"; //generator函数不承认return返回值
console.log("y4"); //不执行,说明return还是能结束函数的执行
}
// 尽量别用表达式创建generator函数!
// var fn=function* (){
// console.log(1);
// var y1=yield "y1";
// console.log(y1);
// var y2=yield "y2";
// console.log(y2);
// return "y3";
// }
var fn = fn(); // 此处调用并不执行函数fn内部代码(普通函数是会执行的),只是生成了遍历器对象,只有在调用next()时才会执行内部代码
console.log(fn); // fn {<suspended>}
// next如果带参数,这个参数代表上一个yield的返回值
console.log(fn.next(1)); // 开始执行函数内部代码,直到遇到yield就停止执行 {value: "y1", done: false}
console.log(fn.next(2)); // 执行第一个yield之后到第二个yield之间的代码 {value: "y2", done: false}
console.log(fn.next(3)); // {value: "y3", done: true} done是true,说明函数不承认这个返回值
console.log(fn.next(4)); // {value: undefined, done: true} 找不到返回值了,done就是true
Async函数:
// - async是generator 语法糖:
// async函数返回一个 Promise 对象。async函数内部return语句返回的值,会成为then方法回调函数的参数。
// - async 函数中,用await 等待一个promise成功状态的执行 ,同时可以获取到promise的返回值;
// - await 下面的代码直接使用返回值;
// - 保证了 代码的上下顺序就是执行顺序
async function fn() {
// try {无异常执行代码} ctach{异常情况时执行的代码}
try {
// await等待promise对象状态为resolve时执行(从回调地狱到promise链式再到符合正常习惯的一行一行代码)
// 定义变量获取返回的数据(如无await,不能直接用变量获取异步数据)
var data1 = await $.ajax("http://10.10.22.62:3000/api/getinfo");
var data2 = await $.ajax("http://10.10.22.62:3000/api/getmatch/" + data1.info[0].cardid);
// 显示数据到页面中
$("body").html(`姓名:${data1.info[0].name} 编号:${data1.info[0].cardid} 双方信息:${data2.info.match.join("VS")}`);
} catch (err) {
alert("没有获取到信息");
}
}
fn(); // 调用函数
相关原理及相互的关系:

2021.08.23_17.00.14.jpg
如图所示:如果一个对象不具备iterator接口,我们又需要遍历它时可以给这个对象添加遍历器生成函数,原理见图解。
对象的iterator接口部署在 对象的Symbol.iterator属性上 —》
该属性实质上相当于一个遍历器生成函数 —》
调用该属性可以返回一个遍历器指针对象 —》
调用该指针对象的next()方法可以遍历对象 —》
对于不具备iterator接口的对象,可以给它添加一个Symbol.iterator属性,属性值为一个遍历器生成函数,那么它就可以被遍历了。。(Generator函数就是这样的遍历器生成函数)