一、生成器
1、生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同
2、生成器其实是一个特殊的函数,用于异步编程
3、以前用的方式都是纯回调函数
比如:node中fs模块,ajax
4、生成器的声明和调用
function+星号+函数名
- function * gen(){
- console.log("hello generator");
- }
-
- let iterator = gen();
-
- //打印这个变量
- console.log(iterator);
-
- //让代码运行,用next方法执行
- iterator.next(); //hello generator
可以看到打印出的对象里有next方法。用next方法执行函数。
5、生成器函数可以有yield语句
yield后面跟表达式或者自变量。
- function * gen2(){
- console.log(111);
- yield '一只没有耳朵';
- console.log(222);
- yield '一只没有尾巴';
- console.log(333);
- yield '真奇怪';
- console.log(444);
- }
-
- let iterator2 = gen2();
- iterator2.next();
- iterator2.next();
- iterator2.next();
- iterator2.next();
6、yield是函数代码的分隔符
调一个next,执行一段函数。
7、用for...of遍历对象
- //for...of遍历
- for(let v of gen2()){
- console.log(v); //输出的值就是yield后的值
- }
8、next()方法的执行返回结果
返回yield后边,这个语句或者自变量的值。
- function * gen3(){
- yield 111;
- yield 222;
- yield 333;
- }
-
- //执行获取迭代器对象
- let iterator3 = gen3();
- console.log(iterator3.next());
- console.log(iterator3.next());
- console.log(iterator3.next());
- console.log(iterator3.next());
二、生成器函数参数
1、生成器传参
往生成器传参数,只有调用next()才能执行代码获取。
2、next传参
第二次调用next()传入的参数,作为第一个yield返回的结果,以此类推。
- function * gen4(args){
- console.log(args);
- let one = yield 111;
- console.log(one);
- let two = yield 222;
- console.log(two);
- let three = yield 333;
- console.log(three);
- }
-
- //执行获取迭代器对象
- let iterator4 = gen4('AAA');
- console.log(iterator4.next());
- //next方法可以传入实参
- console.log(iterator4.next('BBB'));
- console.log(iterator4.next('CCC'));
- console.log(iterator4.next('DDD'));
三、生成器函数实例
1、js本生是单线程的,异步单线程。所以很多操作是异步完成的。比如:IO操作,文件操作,网络操作,数据库操作
2、定时器需求
1s后控制台输出111,2s后输出222,3s后输出333,总共6s。
- function one(){
- setTimeout(()=>{
- console.log(111);
- iterator.next();
- }, 1000);
- }
-
- function two(){
- setTimeout(()=>{
- console.log(222);
- iterator.next();
- }, 2000);
- }
-
- function three(){
- setTimeout(()=>{
- console.log(333);
- iterator.next();
- }, 3000);
- }
-
- function * gen(){
- yield one();
- yield two();
- yield three();
- }
-
- //调用生成器函数
- let iterator = gen();
- iterator.next();
3、模拟获取数据
1s后获取用户数据,1s后获取订单数据,1s后商品数据。
- function getUsers(){
- setTimeout(()=>{
- let data = '用户数据';
- //调用next方法,并且将数据传入
- //它的实参,将作为第一个yield语句的返回结果
- iterator2.next(data);
- }, 1000);
- }
-
- function getOrders(){
- setTimeout(()=>{
- let data = '订单数据';
- iterator2.next(data);
- }, 1000);
- }
-
- function getGoods(){
- setTimeout(()=>{
- let data = '商品数据';
- iterator2.next(data);
- }, 1000);
- }
-
- function * gen2(){
- let users = yield getUsers();
- console.log(users);
- let orders = yield getOrders();
- console.log(orders);
- let goods = yield getGoods();
- console.log(goods);
- }
-
- //调用生成器函数
- let iterator2 = gen2();
- iterator2.next();