- Generator 函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同。执行Generator 函数会返回一个遍历器对象,Generator 除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以一次遍历Generator 函数内部的每一个状 态。
- Generator 函数特征
- functio关键字和函数名之间有一个'*'符号
- 函数内部使用yield表达式
- Generator 实例
function * helloGenerator() { yield 'hello'; yield 'world'; return 'ending'; } let hg = helloGenerator(); // helloGenerator函数有有两个yield表达式,存在三个状态 'hello'/'world'/'ending' hg.next() Object {value: "hello", done: false} // done: false value: "hello"__proto__: Object hg.next() Object {value: "world", done: false} hg.next() Object {value: "ending", done: true} hg.next() Object {value: undefined, done: true}
- 每次调用遍历器next方法就会返回一个有着value和done属性的对象。value表示当前状态的值,done表示是否遍历结束。
- *Generator 函数的调用和普通函数一样,也是在函数名后加上一对圆括号。不同的是,调用Generator 函数后该函数并不执行,返回的也不是函数执行结果。而是一个指向内部的指针对象,也就是遍历器对象。
- yield表达式
- 在Generator 函数中只有调用next方法才会遍历下一个内部状态,所以提供了一种暂停执行的函数,yield表达式就是暂停标志。
- yield 表达式放在普通函数中会报错
- yield放在其他表达式中需要放在圆括号中
yield
表达式用作函数参数或放在赋值表达式的右边,可以不加括号-
// 异步任务封装 function * gen(x) { var url = 'https://api.github.com/users/github'; var res = yield fetch(url); console.log('res:::', res); } var g = gen(); var result = g.next();//返回Promise对象 result.value .then(res => res.json()) .then((data) => { g.next(data) })
- Generator.prototype.throw
-
var g = function *() { try { yield; } catch(e) { console.log('内部捕获',e) } } var i = g(); i.next() try { i.throw('a'); i.throw('b'); } catch(e) { console.log('外部捕获',e) } // 内部捕获 a // 外部捕获 b /* 遍历器对象i连续抛出两个错误,第一个错误被Generator函数体内的catch捕获,i第二次抛出错误,由于Generator函数内部的catch已经执行过了,不会再捕获到这个错误了 ,所以这个错就被抛出了Generator函数体,被外部catch捕获。遍历器对象的i.throw()方法和命令throw new Error(e)是不同的。 */
-
- Generator.prototype.return
-
返回给定的值,并且终结Generator函数,如果调用return方法 不提供参数,则返回值的value=undefined.
-
function * fun() { yield 1; yield 2; yield 3; } var i = fun(); i.next()//Object {value: 1, done: false} i.return('返回')//Object {value: "返回", done: true}
-