迭代器Iterator
迭代模式:是一种设计模式,用于统一迭代过程。
javascript规定如果一个对象有next方法并且该方法返回一个对象,该对象格式如下
{ value:值,done:是否迭代完成(true or false) }
const arr = [1, 2, 3, 4, 5];
//创建迭代器 迭代数组
const iterator = {
i: 0, //当前数组下标
next() {
var result = {
value: arr[this.i],
done: this.i >= arr.length //为true时迭代完成
}
this.i++;
return result
}
}
可迭代对象
可迭代对象都有一个标志属性Symbol.iterator,for of循环用于遍历可迭代对象
//手动创建可迭代对象
var obj = {
[Symbol.iterator]() {
return {
next() {
return {
value: 1,
done: false
}
}
}
}
}
const arr = [1, 2, 3, 4]; //数组是一个可迭代对象
const iterator = arr[Symbol.iterator]();
let result = iterator.next();
while (!result.done) {
const item = result.value;
console.log(item); // 1 2 3 4
result = iterator.next()
}
//等同于上面效果的代码如下,for of相当于是语法糖
for (const item of arr) {
console.log(item) // 1 2 3 4
}
生成器Generator
生成器既是一个迭代器,又是一个可迭代对象
//书写一个生成器函数 function后面加个*
function* method() {
//生成器内部是为了给生成器提供迭代数据
//每次调用生成器的next方法,将导致生成器函数运行到下一个yield关键字位置
//yield关键字只能在生成器函数内部使用,表示产生一个迭代数据
console.log('第一次运行')
let info = yield 1;
console.log(info + 'next传过来的参数')
console.log('第二次')
yield 2;
console.log('第三次')
return '第一次迭代结束done为true时的value返回值'
}
const generator = method(); //注意这一步并不会执行method,只是得到一个迭代器
基于Generator实现async await
//利用生成器实现async await效果
function* task() {
const d = yield 1;
console.log(d) // 1
const resp = yield fetch("http://localhost:8080/test", {
method: 'GET'
});
// console.log(resp) 异步请求服务器端返回的结果
}
run(task)
function run(generatorFunc) {
const generator = generatorFunc();
let result = generator.next(); //启动任务(开始迭代),得到迭代数据
handleResult()
//对result进行处理
function handleResult() {
if (result.done) {
return //迭代完成
}
//若没有完成 迭代的数据可能是一个Promise 或是其他数据
if (typeof result.value.then == 'function') {
//异步
result.value.then(data => {
result = generator.next(data)
handleResult()
}, err => {
result = generator.throw(err)
handleResult()
})
} else {
//同步
result = generator.next(result.value)
handleResult()
}
}
}