什么是 Generator 函数
- Generator 函数是 ES6 提供的一种异步编程解决方案
- Generator 函数内部可以封装多个状态,可以理解为是一个状态机
Generator函数与普通函数的区别
- 调用 Generator 函数,无论该函数有没有 return 返回值,都会返回一个迭代器对象
- 调用 Generator 函数后,函数中封装的代码不会立即执行
定义一个Generator函数
function *gen() {}
- 只需要在 function 后加一个 * 星号,就代表这个函数是一个 Generator 函数
Generator函数结合 yield 关键字一起使用才有意义
function *gen() { console.log(1); yield 'generator1'; // 通过 yield 定义一个状态 console.log(2); yield 'generator2'; // 又定义一个状态 }
- yield 只能在 Generator 函数中才能使用
- yield 会将 Generator 函数分割成多个部分执行,当前 yield 这行及其上一个 yield 之间的为一个部分
- 第一个部分 console.log(1); yield 'generator1'; // 通过 yield 定义一个状态
- 第二个部分 console.log(2); yield 'generator2'; // 又定义一个状态
- 调用 Generator 函数,返回一个可迭代对象 let it = gen(); 通过这个可迭代对象的 next 来执行 yield 切割的部分
-
// 1 it.next(); // { value: 'generator1', done: false }
传递参数
function *gen() { console.log(1); const val1 = yield 'generator1'; // 调用可迭代对象的 next()函数时传递的参数放入 val1 中 console.log(val1) console.log(2); const val2 = yield 'generator2'; // 再次调用可迭代对象的 next()函数时传递的参数放入 val2 中 console.log(val2); } let it = gen(); // 调用Generator函数生成一个可迭代对象
it.next(); // 不能传递参数
it.next('one'); // 将 one 赋值给 val1
it.next('two'); // 将 two 赋值给 val2
- 通过迭代对象第一次调用 next() 函数不能传递参数
通过 Generator 快速实现对象的 Iterator
let obj = { name: 'zhangsan', age: 66, [Symbol.iterator]: function *() { let keys = Object.keys(this); for (let i = 0; i < keys.length; i++) { yield this[keys[i]]; } } } let it = obj[Symbol.iterator]();
it.next(); // { value: 'zhangsan', done: false }
it.next(); // { value: 66, done: false }
it.next(); // { value: undefined, done: true }