JavaScript学习之ES6 ES2015学记笔记(十)-生成器(Generator)续

一个简单的生成器例子:

function* somewords() {
    yield "hello";
    yield "world";
}
for (var word of somewords()) {
    alert(word);
}

每次调用.next()方法,会执行一次yield方法

如何关闭生成器:

先来了解生成器的特性

generator.return()
generator.next()的可选参数
generator.throw(error)
yield*

以前用过的方法:

function dothings() {
    setup();
try {
// ... 做一些事情
} finally {
    cleanup();
}
}
dothings();

其中cleanup()可以用来关闭连接或文件、释放资源,更新dom等操作。

生成器版本:

function* producevalues() {
    setup();
try {
// ... 生成一些值
} finally {
    cleanup();
}
}
for (var value of producevalues()) {
    work(value);
}

ES6会为我们自动执行清理,在前面说过迭代器iterator接口只支持可选的.return()方法,当返回{done:true}会退出自动调用方法

生成器主导模式

       生成器可以用来实现异步编程,完成你用异步回调或promise 链所做的一切,生成器的.next()方法接受一个可选参数,参数稍后会作为 yield 表达式的返回值出现在生成器中。那就是说, yield 语句与 return 语句不同,它是一个只有当生成器恢复时才会有值的表达式。

var results = yield getdataandlatte(request.areacode)

这个过程程序能够返回有用信息,并且可暂停任意时间的生成器,直到有人调用.next({data:..,coffee:...}),将获得变量存储到results并执行下一行代码:

function* handle(request) {
    var results = yield getdataandlatte(request.areacode);
    results.coffee.drink();
    var target = mosturgentrecord(results.data);
    yield updatestatus(target.id, "ready");
}

yield 仍然保持着它的原始含义:暂停生成器,返回值给调用者
普通函数则与之不同,通常更倾向于满足调用者的需求。可以扩展生成器:

function rungeneratoronce(g, result) {
    var status = g.next(result);
    if (status.done) {
    return; // phew!
    }
    // 生成器请我们去获取一些东西并且
    // 当我们搞定的时候再回调它
    doasynchronousworkincludingespressomachineoperations(
    status.value,
    (error, nextresult) => rungeneratoronce(g, nextresult));
}

同时需要创建一个生成器并运行一次:

rungeneratoronce(handle(request), undefined);

生成器一般是生成Promise对象来告诉调用者要作的事情
 

如何销毁生成器

        生成器的错误处理过程:如果出现错误不执行.next()而是转而执行.throw(error);生成器内部抛出的异常总是会传播到调用者。所以无论生成器是否捕获错误, generator.throw(error)都会抛出 error 并立即返回给你。

当生成器执行到一个 yield 表达式并暂停后可以实现以下功能:

  • 调用 generator.next(value),生成器从离开的地方恢复执行。
  • 调用 generator.return(),传递一个可选值,生成器只执行 finally 代码块并不再恢复执行。
  • 调用 generator.throw(error),生成器表现得像是 yield 表达式调用一个函数并抛出错误。
  • 或者什么也不做,生成器永远保持冻结状态
     

结合生成器实现更多功能
 

写一个简单的生成器函数联结两个可迭代对象
 

function* concat(iter1, iter2) {
for (var value of iter1) {
    yield value;
}
for (var value of iter2) {
    yield value;
}}

//ES6
function* concat(iter1, iter2) {
    yield* iter1;
    yield* iter2;
}

普通 yield 表达式只生成一个值,而 yield*表达式可以通过迭代器进行迭代生成所有的值。
可以使用yield*使用生成器调用生成器:

function* factoredoutchunkofcode() { ... }
function* refactoredfunction() {
...
    yield* factoredoutchunkofcode();
...
}

 

本节参考《ES6-In-Depth》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值