JS之Generator(生成器)

来源:互联网 发布:exe解压软件安卓版 编辑:程序博客网 时间:2024/06/07 10:52

这阵子因为要学习React Native,而RN必备的知识就是JS,所以开始学习起来了Js,在此声明写博客就是为了更好的学习,总结一些我学习过程中知识点,有不同意见的请尽情发表!

1. 概述

     Generator 顾名思义是生成器,那什么是生成器?官网给出的解释:使用 function* 语法和一个或多个 yield 表达式以创建一个函数即为生成器,当然它的返回值就是一个迭代器即生成器。下面我们看一个简单的实例:
function* gen(x){  var y = yield x + 2;  return y;}

上面代码就是一个 Generator 函数。它不同于普通函数,是可以暂停执行的,所以函数名之前要加星号,以示区别。其实整个 Generator 函数就是一个封装的异步任务,或者说是异步任务的容器。异步操作需要暂停的地方,都用 yield 语句注明。Generator 函数的执行方法如下:

function* gen(x){

  var y = yield x + 2;

  return y;

}

var g = gen(1);

console.log(g.next());//返回 对象 {value : 3, done : false }

console.log(g.next());//返回 对象 {value : undefined, done : false }

如图:


 上面代码中,调用 Generator 函数,会返回一个内部指针(即遍历器 )g 。这是 Generator 函数不同于普通函数的另一个地方,即执行它不会返回结果,返回的是指针对象。调用指针 g 的 next 方法,会移动内部指针(即执行异步任务的第一段),指向第一个遇到的 yield 语句,上例是执行到 x + 2 为止,再次调用g的next的方法,内部指针指向下个yield语句。

换言之,next 方法的作用是分阶段执行 Generator 函数。每次调用 next 方法,会返回一个对象,这个对象就是具有两个属性(done (done=false) 和 value (value=operand))的 IteratorResult 对象。value 属性是 yield 语句后面表达式的值,表示当前阶段的值;done 属性是一个布尔值,表示 Generator 函数是否执行完毕,即是否还有下一个阶段。这里说明了Generator 函数可以暂停执行和恢复执行,这是它能封装异步任务的根本原

2.迭代器委托

使用yield*可以实现迭代器之间的委托,语法 : yield*  迭代器

function* stringIter() {    var str = "bobsyouruncle";    var idx = 0;    while(idx < str.length)        yield str[idx++];}
function* strIter() {    yield "jo";    yield* stringIter();}var si2 = strIter();console.log(si2.next().value);console.log(si2.next().value);console.log(si2.next().value);console.log(si2.next().value);
输出:
jo
b
o
b
上面的代码则 yield* 委托到 stringIter 生成器。

3.next传递参数

    还可以将参数传递给 next 并使用该参数修改生成器的状态,以创建更高级的生成器。 next 将成为之前执行的 yield 表达式的结果值。在下面的示例中,当你将值 100 传递给 next 方法时,会重置生成器的内部索引值。如下代码:

function* strIter2() {
    var str = "jobob";
    var idx = 0;
    while(idx < str.length) {
        var modify = yield str[idx++];
        if(modify == 100) {
            idx = 0;
        }
    }
 
}
 
var str2 =  strIter2();
 
console.log(str2.next().value);
console.log(str2.next().value);
console.log(str2.next().value);

console.log(str2.next(100).value);

输出:

j

o

b

j

上面的代码给next传递100,内部索引值会被重置为0.

4.throw

genrator还可以处理错误代码:

function* genthrow(x){

  try {

    var y = yield x + 2;

  } catch (e){ 

   console.log("genthrow--------->" + e);

  }

  return y;

}


var thro = genthrow(1);

thro.next();

thro.throw("出错了")

    上面代码的最后一行,Generator 函数体外,使用指针对象的 throw 方法抛出的错误,可以被函数体内的 try ... catch 代码块捕获。这意味着,出错的代码与处理错误的代码,实现了时间和空间上的分离,这对于异步编程无疑是很重要的。


参考一:阮一峰随笔
参考二:MSDN

原创粉丝点击