generator

2021/12/15

# 可迭代协议

可迭代协议

  • 可迭代协议规定了【for...of】迭代的条件是自身或原型链上有[Symbol.iterator]方法
const arr = [1, 2, 3];
console.log(arr[Symbol.iterator]); // [Function: values]
console.log(arr[Symbol.iterator]()); // Object [Array Iterator] {}

const obj = {};
console.log(obj[Symbol.iterator]); // undefined
1
2
3
4
5
6

# 迭代器协议

迭代器协议

  • 迭代器协议规定迭代器函数必须返回一个生成器对象:包含【function next()】的【对象】
  • next() 返回一个指定属性的对象: {done: bool, value: any}

  • 首次执行next()的时候才开始进入执行函数,因此首次next入参无效
  • 后续的next会作为yield表达式的值传入
const arr = [1, 2, 3];

console.log(arr[Symbol.iterator]().next()); // { value: 1, done: false }
1
2
3
  • Object不是可迭代对象,改写成可迭代对象(按照可迭代协议给对象增加迭代器)

遍历自身所有可枚举属性




 








 
 
 






const obj = {
    name: 'hdy',
    age: 18,
    [Symbol.iterator]() {
        let vals = Object.values(this);
        let idx = 0;
        return {
            next:() => idx < vals.length ? {value: vals[idx++], done: false} : {value: undefined, done: true}
        }
    }
};

for (let value of obj) {
    console.log(value); // hdy 18
}


for (let value of obj) {
    console.log(value); // hdy 18
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

利用生成器函数




 
 
 
 
 
 





const obj = {
    name: 'hdy',
    age: 18,
    *[Symbol.iterator]() {
        const vals = Object.values(this);
        for (let val of vals) {
            yield val;
        }
    }
}
for (let value of obj) {
    console.log(value);
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# function*

function*

  • 作用:声明一个生成器函数,
  • 返回:返回可迭代对象【generator】【生成器】

# yield

# 生成器

生成器

  • 生成器对象由generator 【function*】返回,符合可迭代协议和迭代协议。
  • 有以下原型方法:
    1. next
    2. return
    3. throw
  • 时间生成器:每次执行都生成当前的时间
function* generator() {
    while(true) {
        yield new Date().toLocaleString()
    }
}
// generator返回的 生成器gen
const gen = generator();
console.log(gen.next().value);
1
2
3
4
5
6
7
8

# next

  • 作用:调用生成器的下一个值,并且可以传值
  • 调用:generator.next(any)
  • 入参:any
  • 返回:{done: bool, value: any}

入参

  • 第一次调用next的入参无效

# return

return

  • 作用:返回给定值并结束生成器
  • 调用:generator.return(value)
  • 入参:any
  • 返回:{done: true, value: any}

# throw

  • 作用:向生成器抛出异常
  • 调用:generator.throw(new Error(tip))
  • 入参:Error
  • 返回:{value: any, done: bool}
function* generator() {
    let value = 1;
    while(true) {
        try {
            value = yield value;
        } catch(e) {
            console.log(e); // Error: 自定义错误
        }
    }
}

const gen = generator();

console.log(gen.next().value); // 1
console.log(gen.throw(new Error('自定义错误'))); // { value: 1, done: false }

console.log(gen.next()); // { value: undefined, done: false }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
上次更新: 9/17/2024