1,概念:
Generator函数有多种理解角度。从语法上,首先可以把它理解成,Generator函数一个状态机,封装了多个内部状态。
执行Generator函数会返回一个遍历器对象,也就是说,Generator函数除了状态机,还是一个遍历器对象生成函数。
2,特征:
一是,function
关键字与函数名之间有一个星号;
二是,函数体内部使用yield
语句,定义不同的内部状态。(yield语句在英语里的意思就是“产出”)。
3,理解:
Generator函数的调用方法和普通函数一样,但不同的是,调用Generator函数后,该函数并不知晓,返回是也不是函数运行结果,而是一个指向内部状态的指针对象,也就是遍历器对象。
必须调用遍历器对象的next方法,似的指针移动到下一个状态。也就是说,每次调用next
方法,内部指针就从函数头部或上一次定下来的地方开始执行,直到遇到下一个yield
语句(或return
语句)为止。换言之,Generator函数是分段执行的,yield
语句是暂停执行的标记,而next
方法可以恢复执行。
4,总结:
调用Generator函数,返回一个遍历器对象,代表Generator函数的内部指针。以后每次调用遍历器对象的next
方法,就会返回一个有着value
和done
两个属性的对象。 value
属性表示当前的内部状态的值,是yield
语句后面那个表达式的值;done
属性是一个布尔值,表示是否遍历结束。
// 对象方法 //Generator 函数是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行)。 const obj = { * n() { yield ‘hello‘ } } console.log(obj.n().next());//{value: "hello", done: false} // 函数 //整个 Generator 函数就是一个封装的异步任务,或者说是异步任务的容器。 //异步操作需要暂停的地方,都用 yield 语句注明。 function* stateFn(){ yield ‘状态一‘; yield ‘状态二‘; return ‘状态三‘; } var state = stateFn(); console.log(state);//stateFn {<suspended>} console.log(state.next());//{value: "状态一", done: false} console.log(state.next());//{value: "状态二", done: false} console.log(state.next());//{value: "状态三", done: true} console.log(state.next());//{value: undefined, done: true} //next 方法还可以接受参数,这是向 Generator 函数体内输入数据。 function* gen(x){ var y = yield x +2; return y; } var g = gen(1); console.log(g.next());//{value: 3, done: false} //console.log(g.next());//{value: undefined, done: true} //next 方法还可以接受参数 console.log(g.next(9));//{value: 9, done: true} //Generator 函数内部还可以部署错误处理代码,捕获函数体外抛出的错误。 function* hen (x){ try { var y = yield x + 4; }catch(e){ console.log(e);//出错了 } } var h = hen(1); console.log(h.next());//{value: 5, done: false} //这意味着,出错的代码与处理错误的代码, //实现了时间和空间上的分离,这对于异步编程无疑是很重要的。 h.throw("出错了"); console.log(h.next());//{value: undefined, done: true}