Generator生成器函数
Generator函数是ES2015提出的异步的解决方案,与普通的函数有很大的不同;
特点:
(1)generator函数与普通函数不同,普通函数一旦调用就会执行完,但是generator函数中间可以暂停,执行一会歇一会。
(2)在function关键字后面跟一个(*)号;
(3)在函数体内部使用yield表达式作为一个状态,实现暂停;
(4)generator函数执行并不会有什么效果,而是返回一个迭代器对象,之后调用迭代器的next方法会返回一个值对象。
举例说明:
function *go(a){ console.log(1); //yield语句只是标识符,并没有返回值 //yield左边等于next()传来的参数值,没传参则为undefined,yield右边是next()的返回值 let b=yield a; console.log(2); let c=yield b; console.log(3); return c; } let iterator=go('aaa'); let r1=iterator.next();//第一次next()不用传参 console.log(r1);// 1 {value: "aaa", done: false} let r2=iterator.next('bbb'); console.log(r2);//2 {value: "bbb", done: false} let r3=iterator.next(); console.log(r3);//3 {value: undefined, done: true} done属性值代表当前迭代是否完成。 //例2 function *gen(x){ var y=2*(yield (x+1)); var z=yield (y/3); return x+y+z; } var t=gen(5); console.log(t.next());//{value: 6, done: false} console.log(t.next(12));//{value: 8, done: false} console.log(t.next(13));//{value: 42, done: true}解析:yield (x+1)表达式将传递值6到外部,在第二次调用next(12)的时候,传递12到generator函数内部作为yield(x+1)表达式的值,因此y被赋值12*12=24.接下来,下一条yield(y/3)将向外传值值8.第三次调用next(13)传递13到generator函数内部给yield(y/3),所以z的值为13
在生成器中的return值:便利返回对象的done值为true时迭代即结束,不会对该value处理。
function *createIterator() { yield 1; return 42; yield 2; } let iterator1 = createIterator(); console.log(...iterator); // 1
async是Generator函数的语法糖。async的实现原理就是将Generator函数和自动执行器包装在一个函数里。
相比于generator,Async函数有以下几点改进:
(1)内置执行器。generator函数的执行必须依赖执行器,而async函数自带执行器,调用的方式和普通函数的调用一样。
(2)返回值是promise对象。比起generator函数返回的iterator对象更加方便,可以直接使用then()方法调用。
实现一个简单的迭代器
function createIterator(items){ var i=0; return { next:function(){ var done=i>=items.length; var value=!done?items[i++]:undefined; return { value:value, done:done } } } } var t=createIterator([1,2,3,4]); console.log(t.next()); console.log(t.next()); console.log(t.next()); console.log(t.next()); console.log(t.next());
co模块?
用于generator函数的自动执行。是我们可以不用编写generator函数的执行器。
co模块其实是将两种自动执行器(thunk函数和promise对象)包装成一个模块,然后返回的是promise对象。