美文网首页工作生活
ES6 Generator函数

ES6 Generator函数

作者: 萘小蒽 | 来源:发表于2019-07-01 11:02 被阅读0次

Generator函数概念

Generator函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同。
对于Generator函数是有多重理解角度。从语法上,首先可以把它理解成一个状态机,封装了很多个内部状态。

执行Generator函数会返回一个遍历器对象,可以一次遍历Generator函数内部的每一个状态。

Generator函数特征

  1. function命令与函数名之间有一个星号(*);
  2. 函数体内部使用yield语句定义不同的内部状态(yield是产出的意思);
  3. 函数返回的是一个遍历器对象,须调用next方法才会一次返回不同状态的值。
function *helloWorldGenerator(){
 yield 'hello';
 yield 'world';
 return 'ending';
}
var hw = helloWorldGenerator();

上面代码就定义了一个Generator函数--helloWorldGenerator,它内部有两个yield语句,和一个return语句,即该函数有三个状态:helloworld、和 return语句(结束执行)
与其他不同函数不同的是,Generator函数调用之后,该函数并不会执行,返回也不是函数的运行结果,而是一个指向内部状态的指针对象,也就是遍历器对象Iterator,在之后,我们必须调用遍历器对象的next方法,使得指正指向下一个状态,每次调用next方法,内部指针就从函数的头部或者上一次停下来的地方开始执行,直到遇到下一条yield语句,或者return语句为止。

hw.next();
//{value: "hello", done: false}
hw.next();
//{value: "world", done: false}
hw.next();
//{value: "ending", done: true}
hw.next();
//{value: undefined, done: true}

上面一共执行了四次next方法;

yield语句

由于Generator函数返回的遍历器对象只有调用next方法才会遍历下一个内部状态,所以提供了一种可以暂停执行的函数。yield语句就是暂停标志。

  • yield语句,与next方法的运行逻辑
  1. 遇到yield语句就暂停执行后面的操作,并将紧跟在yield后的表达式的值作为返回的对象的value属性值。
  2. 下一次调用next方法时再继续往下执行,直到遇到下一条yield语句。
  3. 如果没有遇到yield语句,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值作为返回对象的value属性的值。
  4. 如果该函数没有return语句,则返回对象的value属性值为undefined,对象的done属性值为true,表示遍历已经结束。
  • yield语句和return语句的区别。

yield语句和return语句的相似之处在于都能返回紧跟在语句后的表达式的值。区别在于每次遇到yield语句函数会暂停执行,下一次会从该位置继续向后执行,而人团语句不具备位置记忆的功能,一个函数里只能执行一次(或者说一条)return语句,但可以执行多次yield语句。

  • Generator函数不用yield语句。
    这时候就变成了一个单纯的暂缓执行函数。
function *noyield(){
   console.log('执行了!')
 }
var  generator = noyield();
generator.next();
//执行了!
  • 普通函数中不能使用yield语句
function fn(){
  yield 1;
}
fn() // SyntaxError: Unexpected number

for...of中使用Generator函数

for...of会自动遍历Generator函数,且不需要再调用 next方法.

function *foo(){
  yield 1;
  yield 2;
  yield 3;
  yield 4;
  return 5;
}
for(let i of foo()){
  console.log(i)
} //1 2 3 4 

上面的代码使用 for...of循环4条yield语句的值,一旦 next方法的返回对象的done属性为true, for...of循环就会终止,且不包含改返回对象,所以上面的return语句返回的6不包括在 for...of循环中。

for...of语句,扩展运算符(···)、解构赋值和Array.from方法内部调用的都是遍历器接口。这意味着它们可以将Generator函数返回的Iterator对象作为参数。

function *numbers(){
  yield 1;
  yield 2;
  return 3;
  yield 4;
}
//扩展运算符
[...numbers()]//[ 1, 2 ];
//Array.from
Array.from(numbers()) //[ 1,2 ]
//解构赋值
let [ x, y ] = numbers()
x  //1
y  //2
//for...of 
for (let i of numbers()){
    console.log(i)
}
//1
//2 

Generator.prototype.throw();

Generator函数返回的遍历器都有一个throw方法,可以在函数体外抛出错误,然后在体内捕获。

var g = function *(){
  while(true){
    try{
       yield;
      }catch(e){
        if(e!='a') throw e 
         console.log('内部捕获',e)    
     }
   }
} 
var i = g();
i.next();
try{
  i.throw('a');
  i.throw('b');
}catch(e){
  console.log('外部捕获',e);
}
//内部捕获 a
//外部捕获 b

上面代码中,遍历器对象i连续抛出错误。第一个错误被Generator函数体内catch捕获,然后Generator函数执行完成,于是第二个错误被函数体外的catch语句捕获。

Generator.prototype.return();

  • Generator函数返回的遍历器对象还有一个return方法,可以返回给定的值,并终结Generator函数的遍历。
function *numbers(){
  yield 1;
  yield 2;
  return 3;
  yield 4;
}
var num = numbers();
num.next();  
// {value: 1, done: false}
num.return('stop');  
//{value: "stop", done: true}
num.next();
//{value: undefined, done: true}

上面函数在遍历器num调用return方法后,遍历终止,返回值的donetrue,之后调用next方法总是会返回true

  • 如果Generator函数内部有try...finally代码块,namereturn方法会推迟到finally代码块执行完再执行。
function *numbers(){
   try{
      yield 1;
      yield 2;
   }finally{
      yield 3;
      yield 4;
   }
   yield 5;
};
var num = numbers();
num.next();  
//{value: 1, done: false}
num.next();  
//{value: 2, done: false}
num.return();  
//{value: 3, done: false}
num.next();  
//{{value: 4, done: false}
num.next();  
//{value: 6, done: true}

总结

  • Generator函数是分段执行的,yield语句是暂停执行的标记,而next方法可以恢复执行。
  • Generator函数它返回一个遍历器对象,代表Generator函数的内部指针。
  • Generator函数它可以返回一系列的值,因为它可以有人以多条yield语句。
  • yield语句是Generator函数特有的(也仅限于它),将紧跟在yield后的表达式的值作为返回的对象的value属性值。
  • 使用 for...of循环运行的Generator函数,不需要调用next方法,在next的返回对象done属性为true时,for...of循环终止。(扩展运算符,Array.from,解构赋值,都可以使用Generator函数返回的Iterator对象作为参数)

相关文章

  • 03-JavaScript-Generator异步编程

    Generator 概念 Generator 函数是 ES6 提供的一种异步编程解决方案 Generator 函数...

  • co库的简易实现

    generator Generator 函数是 ES6 提供的一种异步编程解决方案。 执行generator函数会...

  • JavaScript异步处理——Generator及async函

    Generator Generator 函数是 ES6 提供的一种异步编程解决方案。Generator函数在fun...

  • Generator函数介绍

    什么事Generator函数 Generator函数是ES6提供的一种异步编程解决方案, 可以把Generator...

  • 20.ES6中Generator生成器

    Generator是ES6的生成器1、Generator 函数是 ES6 提供的一种异步编程解决方案,在函数中可以...

  • Generator 函数

    Generator Generator 函数是 es6 中的新的异步编程解决方案,本节仅讨论 Generator ...

  • Generator函数实现斐波那契数列

    ES6 中 generator生成器函数 特点: 调用generator函数返回一个迭代器(iterator)对象...

  • Generator函数

    Generator 函数是 ES6 提供的一种异步编程解决方案。调用 Generator 函数后,该函数并不执行,...

  • 关于es6新属性yield

    关于es6新属性yield yield是Generator函数中中断函数返回的一个属性。Generator函数即一...

  • redux-saga学习笔记

    1.Generator函数 Generator函数时ES6提供的一种异步编程解决方案,函数调用后,函数并不执行,返...

网友评论

    本文标题:ES6 Generator函数

    本文链接:https://www.haomeiwen.com/subject/msivcctx.html