16.1.0 generator函数的语法
2018-01-15 11:24
211 查看
16.1.1 基本概念
一:generator是ES6提供的一种异步编程解决方案,执行语法跟传统函数完全不同;二:(1)语法上看,理解成一个状态机,封装了多个内部状态;
(2)形式上看,generator是一个普通的函数,但是具备2个特征:
A:星号
B:函数体内可以使用多个yield语句定义不同的内部状态;
三
1:执行generator函数会返回一个遍历器对象;也就是说generator函数除了是一个状态机,还是一个遍历器对象生成函数;返回的的遍历器对象的next方法也是一个对象:如下:
{ value: , //yield语句后面的值或者undefined done: //表示是否执行完毕;true或者false }
2:可以用next方法依次遍历generator函数内部的每个状态;
function* gen(x){ var y = yield x + 2; var z = yield y + 2; var p = yield 3 + 2; yield p return z; } var g = gen(1); console.log(g) // {} console.log(g.next()) // { value: 3, done: false } console.log(g.next()) // { value: NaN, done: false } console.log(g) // {} console.log(g.next()) // { value: 5, done: false } console.log(g.next()) // { value: undefined, done: true } console.log(g) // {}
3:下面的写法直接报错
function gen(x){ // yield let y = x + 2; //直接报错 // var z = yield y + 2; //直接报错 // yield z // return z; // }
注:第一次调用next后,y的值并不是3;所以第二次next以后,返回NaN;
4:由于ES6并没有规定星号出现的位置,因此下面的写法都是正确的,一般用第三种;
function * gen(x){} function *gen(x){} function* gen(x){} function*gen(x){}
三:generator中的代码不会立即执行,只有第一次调用next方法才会执行第一行代码;下面的代码2秒钟执行才会打印结果
function* gen() { console.log('ok') } var generator=gen() setTimeout(function () { generator.next() },2000)
16.1.2 yield表达式
一:遍历器对的next方法的运行逻辑如下:1:遇到yield语句就暂停执行后面的操作,并且将紧跟在yield后的表达式的值作为返回的遍历器对象的value值;done返回false
2:下一次调用next方法时,继续往下执行,直到遇到下一条yield语句;done返回false
3:如果没有遇到yield语句,就一直运行到函数结束;直到return语句;并且将return语句后面表达式的值作为返回对象的value值
4:如果没有return语句,就将返回对象的value值返回undefined;done返回true
二:yield不能用在其他普通函数中;不然会报错
var arr = [1, [[2, 3], 4], [5, 6]] //语法错误:普通函数中使用yield表达式 // var flat = function* (a) { // a.forEach(function (item) { // if (typeof item !== 'number') { // yield* flat(item) // } else { // yield item // } // }) // }
下面的代码才是正解
var arr = [1, [[2, 3], 4], [5, 6]] var flat = function* (a) { var length=a.length for(var i=0;i<length;i++){ var item=a[i] if(typeof(item)!=='number'){ yield* flat(item) }else{ yield item } } } for(var f of flat(arr)){ console.log(f) }
三:yield表达式如果在另外一个表达式中,必须放在()中
function* deom() { // console.log('hello'+ yield ) //SyntaxError // console.log('hello'+ yield 123) ///SyntaxError console.log('hello'+ (yield) ) console.log('hello'+ (yield 123)) }
16.1.3 generator根iterator的关系
1:任何一个对象的Symbol.inetrator方法=该对象的遍历器对象生成函数;调用该函数返回该对象的一个遍历器对象2:由于generator函数就是遍历器生成函数,因此可以把generator复制给对象的Symbol.iterator属性,从而使得改对象具有Iterator接口;该接口可以被…运算符遍历
var myIterable = {} myIterable[Symbol.iterator] = function* () { yield 1; yield 2; yield 3; } console.log(myIterable) //{ [Symbol(Symbol.iterator)]: [GeneratorFunction] } console.log(...myIterable) //1 2 3
3:generator函数执行后返回的遍历器对象,也具有Symbol.inetrator属性,执行后返回自身;
function* gen() { } var g=gen() console.log(g[Symbol.iterator]()===g) //true
相关文章推荐
- Generator函数语法解析
- Generator函数语法解析
- Generator函数语法解析
- Generator函数语法解析
- Generator 函数的语法
- ES6学习笔记之Generator 函数的语法
- Generator函数语法解析
- ES6 —(Generator 函数的语法)
- Generator函数语法解析
- Generator函数语法解析
- Generator函数语法解析
- Generator函数语法解析
- Generator函数语法解析
- Generator函数语法解析
- Generator函数语法解析
- 常用函数语法
- 详解Makefile 函数的语法与使用 (转)
- Oracle语法之OVER(PARTITION BY)及开窗函数
- Kotlin语法学习-变量定义、函数扩展、Parcelable序列化等简单总结
- Shell 语法之函数