ES6之Generator函数(4)知识点总结(十一)

news/2024/7/4 0:53:49 标签: Generator

Generator函数的数据交换和错误处理。

Generator函数可以暂停执行和恢复执行,这是它能封装异步任务的根本原因。除此之外,它还有两个特性,使他可以作为异步编程的完整解决方案:函数体内的数据交换和错误处理机制。next返回值的value属性,是Generator函数向外输出数据,next方法还可以接受参数,向Generator函数体内输入数

function *g(x){
    yield "leo";
  var y=  yield  "lalalal"+x;
    return y;

}
var p = g(1);
console.log(p.next());// { value: "leo", done: false }
console.log(p.next('donna'));//{ value: "lalalal1", done: false }
console.log(p.next("honery"));//{ value: "honery", done: true }
console.log(p.next("honery"));// { value: undefined, done: true }

Generator函数内部还可以部署错误处理代码,捕获函数体外抛出的错误

    try {
        var y = yield x + 2;
    } catch (e){
        console.log(e);
    }
    return y;
}

var g = gen(1);
console.log(g.next());//{ value: 3, done: false }
g.throw('出错了');
console.log(g.next(12));//{ value: undefined, done: true }

上面的代码,在Generator函数体外,使用指针对象的throw方法抛出的错误,可以被函数体内的try…catch代码块捕获。这意味着,出错的代码与处理错误的代码,在时间和空间上的分离。

再看一个例子

function* gen(x){
    try {
        var y = yield x + 2;
    } catch (e){
        console.log(e);
    }
    yield "donna";
    return y;
}

var g = gen(1);
console.log(g.next());//{ value: 3, done: false }
console.log(g.throw('出错了'));//{ value: "donna", done: false }
console.log(g.next(12));//{ value: undefined, done: true }

我们之前说过,go.throw方法被捕获以后,自动执行了一次next方法,但从上面的两个例子中我们可以发现,go.throw方法只会自动执行yield语句,但并不自动执行return语句,这和调用next方法还是有区别的。当然,只要Generator函数内部部署了try…catch代码块,那么遍历器的throw方法抛出的错误,不影响下一次遍历,这也是从上面的代码中可以看到的。


之前忽略了next方法参数的作用,今天给补上

next方法的参数:

yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当做上一个yield表达式的返回值。

注意,由于next方法的参数表示上一个yield表达式的返回值,所以,在第一次调用next方法时,传递的参数是无效的,只有第二次调用next方法,传递的参数才是有效的。从语法上讲,第一个next方法用于启动遍历器对象,所以不用带参数。

看个例子

function *g(x){
    yield 2+x;
  var y=  2*(yield  3+x);
  yield y;
    return y+x;

}
var p = g(1);
console.log(p.next());// { value: 3, done: false }
console.log(p.next(7));// { value: 4, done: false }
console.log(p.next(5));// { value: 10, done: false }
console.log(p.next(5));// { value: 11, done: false }
console.log(p.next(6));// { value: undefined, done: false }
切记:next方法返回的是yield表达式后面的值,next方法传递的参数不是x的值,而是上一个yield表达式的返回值(不是上一个整个表达式的值,知识yield后面的值)。所以上面的代码,第一次调用next方法时,返回的是2+x,x=1,所以就是3,第二次调用next方法,虽然传递了参数,但它代表的上一个yield表达式的值,而我们并没有使用这个值,第三次调用next方法的时候,传递的参数为4,说明上一个yield表达式3+x=5,所以y = 2*5=10,所以这一次yield的值为10,第四次调用next方法,由于y=10,x=1,所以返回的结果就是11.
function *g(x){
    yield 2+x;
  var y=  2*(yield  3+x);
  yield y+1;
    yield y+x;

}
var p = g(1);
console.log(p.next());// { value: 3, done: false }
console.log(p.next(7));// { value: 4, done: false }
console.log(p.next(5));// { value: 11, done: false }
console.log(p.next(5));// { value: 11, done: false }此处y=10,x=1
console.log(p.next(6));// { value: undefined, done: false }
    function *g(x){
        yield 2+x;
        var y=  2*(yield  3+x);
       var z =  yield y+1;
        yield z+x+y;

    }
    var p = g(1);
    console.log(p.next());// { value: 3, done: false }
    console.log(p.next(7));// { value: 4, done: false }
    console.log(p.next(5));// { value: 11, done: false }
    console.log(p.next(5));// { value: 16, done: false }此处z=5,y=10,x=1
    console.log(p.next(6));// { value: undefined, done: false }

还有下面的情况

    function *g(x){
        yield 2+x;
        var y=  2*(yield  3+x);
       var z =  yield 1;
        yield z+x+y;

    }
    var p = g(1);
    console.log(p.next());// { value: 3, done: false }
    console.log(p.next(7));// { value: 4, done: false }
    console.log(p.next(5));// { value: 1, done: false }
    console.log(p.next(5));// { value: 16, done: false }
    console.log(p.next(6));// { value: undefined, done: false }
    function *g(x){
        yield 2+x;
        var y=  2*(yield  3+x);
       var z =  yield 1;
        yield z+x+y;

    }
    var p = g(1);
    console.log(p.next());// { value: 3, done: false }
    console.log(p.next(7));// { value: 4, done: false }
    console.log(p.next());// { value: 1, done: false }
    console.log(p.next(5));// { value: NaN, done: false }
    console.log(p.next(6));// { value: undefined, done: false }

做一个小小的总结:next方法返回一个对象,它的value属性就是当前yield表达式的值(此处暂且不讨论done属性的值),如果next方法在调用的时候传递了参数(不包括第一个调用next方法),那么这个参数就是上一个yield表达式的返回值,也可以说就是当上一个yield表达式整体(或yield整体运算后)赋值给了一个变量,而下一次调用next方法,上一个yield表达式的值就是本次next方法的参数,如果没有传参,则为undefined。(还有就是不要和next参数和Generator参数搞混喽)

这几个对比,每一个改动都很小,把我的疑惑的疑惑解决了,我自己总结了一下,可能有些说法不太科学,仅供参考(当然如果哪里说法不对,也希望您可以提出您的宝贵意见),实践才是检验真理的唯一标准,嗯、还是要多动手才是。



http://www.niftyadmin.cn/n/952068.html

相关文章

Ajax.NET 和 Atlas 区别

Ajax.NET是一款免费的面向.Net的Ajax LibraryAtlas是微软提供给开发者的Ajax开发包两者都可以让ASP.Net具备Ajax功能 近日,利用空闲时间把这两个东西做了不完全的比较1、代码量由于两者通过不同途径实现Ajax,所以代码的量也是不相同的,下面我…

anaconda新建python2环境安装不了jupyterlab_Anaconda+pycharm(jupyter lab)搭建环境

之前先是安装了pycharm,手动安装了python2.7和3.7版本,在pycharm里面使用alt/手动下载包。后来想使用jupyter lab,手动下载包太麻烦且有版本管理的文艺,于是打算装Anaconda。anaconda里面集成了包括python在内的很多工具&#xff…

ES6之async函数(1)知识点总结(十二)

每天集中精力学一会ES6,效果还是蛮好的,嗯,跟着阮一峰大神学功夫喽,如果你也见识见识阮一峰大神的神功,请点击http://es6.ruanyifeng.com/#docs/async async函数的写法和语法: 1、async函数就是将Generator…

.net事务

.net中的4种事务总结 在一个MIS系统中,没有用事务那就绝对是有问题的,要么就只有一种情况:你的系统实在是太小了,业务业务逻辑有只要一步执行就可以完成了。因此掌握事务处理的方法是很重要,进我的归类在.net中大致有以下4种事务处理的方法。大家可以参考…

H5中的自定义数据属性

H5规定可以为元素添加非标准的属性,但要添加前缀data-,目的是为元素提供与渲染无关的信息,或者提供语义信息。这些属性可以任意添加,随便命名,只要以data-开头即可 添加了自定义属性后,可以通过dataset属性…

单页网站制作系统_这4个网站制作技巧,教你做美观的单页网站

现在单页面网站开始很受欢迎,技术小白做一个单页网站也比较方便省时,那么如何才能把单页面网站做得美观呢?制作网站需要哪些技巧?今天就跟大家分享4点网站首页制作技巧,教你做出好看的网站:1.网站banner 制…

Crystal Reports for Visual Studio 2005 学习一(报表绑定方案)

一. ReportDocument 对象模型的报表绑定二.CrystalReportViewer 对象模型进行报表绑定。) 转载于:https://www.cnblogs.com/zhangzheny/archive/2007/11/16/961140.html

ES6之Class类知识点总结(十三)

好的文章就要分享出来,让更多的小伙伴看到、嗯、继续推荐阮一峰大神的ES6文章,真的很棒,关于Class类的知识,想要了解的更清楚的建议到大神的官网走一走http://es6.ruanyifeng.com/#docs/class-extends 我们知道ES5及之前是没有类的…