1. Generator
1.1 使用方法
function * loop () {
for (let i = 0; i < 4; i++) {
yield console.log(i)
}
}
const l = loop()
l.next() // 1
l.next() // 2
l.next() // 3
l.next()
1.2 next
function * gen () {
let val
val = yield [1, 2, 3]
console.log(val)
}
let l = gen()
l.next() // {value: [1, 2, 3], done: false} value是当前的值 done是函数是否结束
l.next()
yield * 表示后面是一个可迭代的对象,并且还可以是一个Generator函数
function * gen () {
let val
val = yield * [1, 2, 3]
console.log(val)
}
let l = gen()
l.next() // {value: 1, done: false}
l.next() // {value: 2, done: false}
l.next() // {value: 3, done: false}
l.next() // {value: undefined, done: true}
1.3 控制函数内部运行数据
function * gen () {
let val
val = yield [1, 2, 3]
console.log(val)
}
let l = gen()
l.next(10) // 找到第一个yield 解析后面数组 结束
l.next(20) // 改变yield返回值 赋值给val
1.4 中止generator
function * gen () {
let val
val = yield [1, 2, 3]
console.log(val)
}
let l = gen()
l.next(10) // 找到第一个yield 解析后面数组 结束
l.return() // 终止generator
1.5 generator抛出异常 捕获异常
function * gen () {
while (true) {
try {
yield 1
} catch (e) {
console.log(e)
}
}
}
const l = gen()
console.log(l.next())
console.log(l.next())
console.log(l.throw(new Error('error')))
console.log(l.next())
2.Iterator
2.1 如何让不支持遍历的数据结构“可遍历”
let authors = {
example: {
a: [1,2,3],
b: [3,4,5]
},
test: [2,4]
}
authors[Symbol.iterator] = function () {
let allAuthors = this.example // this就是authors
let keys = Object.keys(allAuthors)
let values = []
return {
next () {
if (!values.length) {
if (keys.length) {
values = allAuthors[keys[0]]
keys.shift()
}
}
return {
done: !values.length,
value: values.shift()
}
}
}
}
let r = []
for (let value of authors) {
r.push(value)
}
console.log(r)
2.2 Generator写法
let author = {
allAuthor: {
china: ['a', 'b', 'c'],
japan: ['n', 'd', 's'],
other: [1, 2, 3]
}
}
author[Symbol.iterator] = function * () {
let authors = this.allAuthor
let keys = Object.keys(authors)
let values = []
while (true) {
if (!values.length) {
if (keys.length) {
values = authors[keys[0]]
keys.shift()
yield values.shift()
} else {
return false
}
} else {
yield values.shift()
}
}
}
let result = []
for (let value of author) {
result.push(value)
}
console.log(result)