生成器和迭代器

自作多情 提交于 2019-11-28 10:28:07

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对象。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!