学而逆水行舟,不进则退;
Generator简介
迭代器Iterator
- 迭代器Iterator 是ES6引入的一种新的遍历机制,同时也是一种特殊的对象,它具有一些专门为迭代过程设计的专有接口,每个迭代器对象都有一个next()方法,每次调用都返回一个当前结果对象,当前结果对象中有2个属性;
- value 当前属性的值
- done 用于判断是否遍历结束,当没有更多课返回的数据时候,返回true
- 每调用一次 next()方法,都会返回下一个可用的值,知道遍历结束
const obj = {
name:'mushi'
id:1,
// 迭代器的属性
[Symbol.interator]:() => {
// 读取对象键链表
const keys = Object.keys(this);
let index = 0;
// 报错this,next中的function会有自己的this
const that = this;
return {
next: () => {
// 防止越界
if (index < keys.length) {
const key = keys[index];
index++; // 移动到下一个位置
return {
value: [key, that[key], // 键值对数组
done: false
}
}
// 遍历结束
return {
done:true
}
}
}
}
}
生成器 Generator
- 生成器 是一种返回迭代器的函数,通过function 关键字后的星号(*)函数中的新的关键字yield, *号可以紧挨着function关键字,也可以在中间添加一个空格 例如:
function* generator() {
const arr = [1,2,3];
for(let i of arr) {
yield i;
}
}
let generatorFn = generator();
console.log(generatorFn.next()); // {value: 1, done:false}
console.log(generatorFn.next()); // {value: 2, done:false}
console.log(generatorFn.next()); // {value: 3, done:false}
console.log(generatorFn.next()); // {value: undefined, done:true}
特性
- 每当执行完一条 yield语句后函数就会自动停止运行,直到再次调用next()
- yield 关键字只可在生成器内部使用,在其他地方使用会导致程序抛出错误
- 可以通过函数表达式来创建生成器,但是不能使用箭头函数
let generator = function *() {}
async 和 await
async函数简介
- async 函数返回的就是一个Promise对象,async 函数包含了函数语句、函数表达式、lambda表达式 都会返回一个Promise对象,如果在函数中return 一个变量或者字符串等等, async 会把这个return返回的东西直接通过Promise.resolve()封装成Promise对象
很明显 async返回的就是一个promise对象
如果async 在没有await一起使用的话,可以配合then返回
await
- await 的意思就是等待,后面可以跟着一个表达式,如果值是(字符串、数字、普通对象等),返回值就是本身的值
- 最常用的是后面跟着一个promise对象,await 会等待promise的状态从pending到fulfilled或者rejected, 在此期间他会阻塞,延迟执行await后面的语句
- 如果promise对象的结果是resolve,他会将resolve的值作为await表示示的运算结果
function asyncFn() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if(true) {
console.log('reslove xxxxxx');
resolve('resolve 123');
} else {
reject('reject xxxx');
}
},2000);
});
}
// promise
asyncFn().then((res) => {
console.log('res');
}, (error) => {
console.log(error);
});
//await
tyr{
const res = asyncFn();
console.log(res);
} catch(e) {
console.log(e);
}
// 如果还有第二次请求的话,promise 需要在then方法继续调用,在用then接受
- 封装一个函数 让generator自动执行完毕
function* generator() {
const arr = [1,2,3];
for(let i of arr) {
yield i;
}
}
function timeFn(time) {
return new Promise(resolve => {
setTimeout(() => {
resovle(time);
}, time);
});
}
function asyncFn() {
const iterator = generator();
const next = (res) => {
const { vlue, done } = interator.next(res);// 第二次执行,并接收第一次请求的结果 value和done
}
if (done) return; // 执行完毕直接返回
value.then(res => {
next(res); // 当第一次value 执行完毕且成功的时候,执行下一步
});
next();
}
asyncFn(function* () {
let data = yield timeFn(1000);
console.log(data);
data = yield timeFn(2000);
console.log(data);
return data;
});